...
 
Commits (59)
......@@ -11,6 +11,7 @@ const headPkgs = [
// 'QuotaSelect',
// 'RealTimeInfo',
// 'TimeRangePicker',
'AlarmScrollAssembly',
];
const pkgList = ['base-components', 'extend-components']
.map((dir) => {
......@@ -23,7 +24,8 @@ const tailPkgs = pkgList
.filter((pkg) => pkg.charAt(0) !== '.' && !headPkgs.includes(pkg))
.map((item) => {
const [name, path] = item.split('!');
return `${path}/${name}`;
// return `${path}/${name}`;
return `${name}`;
});
const type = process.env.BUILD_TYPE;
......
......@@ -44,4 +44,5 @@ host/
webpack.host.js
.env
.env.local
\ No newline at end of file
.env.local
yarn.lock
\ No newline at end of file
......@@ -103,6 +103,7 @@ export default {
'DatePickerCustom',
'SelectCustom',
'TreeCustom',
'AlarmScrollAssembly',
],
},
{
......@@ -123,6 +124,7 @@ export default {
'EC_HistoryInfo',
'EC_RealTimeInfo',
'EC_ConfigurationView',
'EC_HistoryView',
],
},
],
......
const proxyURL = process.env.PANDA_ENV_PROXY || 'http://192.168.10.150:8669';
const proxyURL = process.env.PANDA_ENV_PROXY || 'http://192.168.8.28:8911';
export default {
'/api': {
target: 'http://192.168.10.150:8669',
target: proxyURL,
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
......@@ -16,4 +16,14 @@ export default {
'/PandaMonitor': '/PandaMonitor',
},
},
'/PandaCore': {
target: proxyURL,
changeOrigin: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
pathRewrite: {
'/PandaCore': '/PandaCore',
},
},
};
......@@ -122,6 +122,7 @@
"slash2": "^2.0.0",
"style-loader": "^2.0.0",
"stylelint": "^13.0.0",
"swiper": "^6.8.1",
"terser-webpack-plugin": "^5.1.1",
"typescript": "^4.1.2",
"umi": "^3.5.20",
......@@ -144,7 +145,9 @@
"registry": "https://g.civnet.cn:4873"
},
"dependencies": {
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@wisdom-components/basictable": "^1.5.14",
"@wisdom-components/ec_historyview": "^1.4.3",
"@wisdom-components/empty": "^1.3.9",
"@wisdom-components/exportexcel": "^1.1.2",
"@wisdom-components/loadbox": "1.1.4",
......@@ -154,13 +157,17 @@
"cross-spawn": "^7.0.3",
"echarts": "^5.4.0",
"echarts-for-react": "^3.0.2",
"file-loader": "^6.2.0",
"form-render": "^0.9.12",
"highcharts": "^9.0.1",
"highcharts-react-official": "^3.0.0",
"js-export-excel": "^1.1.4",
"jszip": "^3.5.0",
"less": "^3.13.1",
"mqtt-client": "^1.0.12",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"parseForm": "1.0.0",
"react-redux": "^8.0.5",
"sha1": "^1.1.1"
},
"size-limit": [
......
# Change Log
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.6.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/alarmscrollassembly@1.5.0...@wisdom-components/alarmscrollassembly@1.6.0) (2023-01-12)
### Features
- 删除部分注释 ([7e83e3a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7e83e3aec12af4c025267e79b84313e99c8a5f7a))
# [1.5.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/alarmscrollassembly@1.4.0...@wisdom-components/alarmscrollassembly@1.5.0) (2023-01-12)
### Features
- 变更设备报警的实现方式 ([f495636](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/f495636f9327c8fafac32ed89d0c01216981359c))
# [1.4.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/alarmscrollassembly@1.3.0...@wisdom-components/alarmscrollassembly@1.4.0) (2022-12-22)
### Features
- 修复依赖缺失的问题 ([bb57afc](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/bb57afc8768147b0fd7369e7461dd23ccca4d41b))
# [1.3.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/alarmscrollassembly@1.2.1...@wisdom-components/alarmscrollassembly@1.3.0) (2022-12-22)
### Features
- 给定滚动组件最小宽度 ([dd733de](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/dd733de16f755632cfa36e23b3c6669738ebdc3d))
## [1.2.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/alarmscrollassembly@1.2.0...@wisdom-components/alarmscrollassembly@1.2.1) (2022-12-22)
### Bug Fixes
- 去除多余代码,修复未使用代码导致的错误 ([ce66e5b](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/ce66e5bec7d4bf4d1dc15e236e9eb73701f1a649))
# 1.2.0 (2022-12-22)
### Features
- 删除未使用图片 ([dd1d11a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/dd1d11aafe8a88caacfeb8a5c9689f49e877ab3d))
- 新增 alarmscrollassembly ([e7a194d](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e7a194d1d76cebcd27cce4a9525fe23a3b26881b))
- 修改组件名称 ([38351e2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/38351e2c3642a1dfc8e0c504ca3f9a3526d8e1e3))
# 1.1.0 (2022-12-22)
### Features
- 删除未使用图片 ([dd1d11a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/dd1d11aafe8a88caacfeb8a5c9689f49e877ab3d))
- 新增 alarmscrollassembly ([e7a194d](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e7a194d1d76cebcd27cce4a9525fe23a3b26881b))
# `@wisdom-components/AlarmScrollAssembly`
> TODO: description
## Usage
```
const alarmScrollAssembly = require('@wisdom-components/AlarmScrollAssembly');
// TODO: DEMONSTRATE API
```
{
"name": "@wisdom-components/alarmscrollassembly",
"version": "1.6.0",
"description": "滚动组件",
"author": "chenlong <857265978@qq.com>",
"homepage": "",
"license": "ISC",
"sideEffects": [
"*.less"
],
"module": "es/index.js",
"main": "lib/index.js",
"files": [
"lib",
"es",
"dist"
],
"directories": {
"lib": "lib",
"es": "es",
"dist": "dist",
"test": "__tests__"
},
"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"
},
"dependencies": {
"@babel/runtime": "^7.17.9",
"swiper": "^6.8.1"
}
}
---
title: AlarmScrollAssembly - 滚动条
nav:
title: 基础组件
path: /components
group:
path: /
---
# `@wisdom-components/AlarmScrollAssembly`
> TODO: description
## Usage
```
const alarmScrollAssembly = require('@wisdom-components/AlarmScrollAssembly'); // 宽度为930px
// TODO: DEMONSTRATE API
```
<code src="./demos/index.js">
import React, { useEffect, useState } from 'react';
import styles from './NormChart.less';
import { monitorService } from '../api';
import { Checkbox, Row, Input, Tooltip, Tag, Spin } from 'antd';
import ECHistoryInfo from '@wisdom-components/ec_historyinfo';
import HistoryView from '@wisdom-components/ec_historyview';
const { Search } = Input;
const CheckboxGroup = Checkbox.Group;
const NormChart = (props) => {
const { deviceType, deviceCode, info } = props;
const [normList, setNormList] = useState([]);
const [checkedList, setCheckedList] = useState([info.sensorName]);
const [searchStr, setSearchStr] = useState('');
const [normListLoading, setNormListLoading] = useState(false);
const getPumpConfig = () => {
setNormListLoading(true);
monitorService
.GetDeviceQuotaList({
accountName: deviceType,
})
.then((res) => {
if (res.code === 0) {
setNormList(res.data);
} else {
setNormList([]);
}
setNormListLoading(false);
})
.catch((err) => {
console.log(err);
setNormListLoading(false);
});
};
const onChange = (e) => {
setCheckedList(e);
};
const search = (e) => {
setSearchStr(e.target.value);
};
useEffect(() => {
getPumpConfig();
}, []);
return (
<div className={styles.normChart}>
<div className={styles.listWrapper}>
<div className={styles.normList}>
<h3 className={styles.listTitle}>泵房指标</h3>
<Search onChange={search} style={{ marginBottom: 10 }} />
<CheckboxGroup
style={{ height: 'calc(100% - 77px)', overflowY: 'scroll' }}
onChange={onChange}
value={checkedList}
>
<div style={{ display: 'flex', flexDirection: 'column', overflowY: 'scroll' }}>
{normList
.filter((item) => item.name.includes(searchStr))
.map((item) => {
return (
<Row style={{ width: 'calc(100% - 20px)' }}>
<Checkbox value={item.name}>
<Tooltip title={item.name}>
<div
style={{
width: '120px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{item.name}
</div>
</Tooltip>
</Checkbox>
</Row>
);
})}
</div>
</CheckboxGroup>
</div>
</div>
<div className={styles.chartWrapper}>
<Spin className={styles.normSpin} spinning={normListLoading} />
{checkedList && checkedList.length ? (
<div className={styles.selectedNorm}>
<h3 className={styles.listTitle}>已选指标</h3>
<div className={styles.selectedNormWrapper}>
{checkedList.map((item) => {
return (
<Tag
style={{ marginBottom: 8 }}
closable
color="#108ee9"
onClose={() => {
let _checkedList = [...checkedList];
_checkedList = _checkedList.filter((checked) => checked !== item);
setCheckedList(_checkedList);
}}
>
{item}
</Tag>
);
})}
</div>
</div>
) : (
''
)}
<div className={styles.chart}>
{checkedList && checkedList.length && (
<HistoryView
title={'历史数据'}
deviceParams={[
{
deviceCode,
deviceType,
sensors: checkedList.join(','),
},
]}
/>
)}
</div>
</div>
</div>
);
};
export default NormChart;
@import '~antd/es/style/themes/default.less';
.normChart {
display: flex;
width: 100%;
height: 100%;
.listWrapper {
width: 160px;
margin-right: 40px;
.normList {
height: 600px;
padding: 12px 14px 0 6px;
overflow: scroll;
//padding-top: 7px;
box-shadow: 1px 0 0 0 #eeeeee;
.listTitle {
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
}
}
}
.chartWrapper {
position: relative;
flex: 1;
.normSpin {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.selectedNorm {
padding: 10px 0;
.selectedNormWrapper {
height: 50px;
overflow-y: scroll;
}
}
.filters {
}
.chart {
width: 100%;
height: 500px;
}
}
}
import { Modal, notification } from 'antd';
import { instanceRequest, service } from '@wisdom-utils/utils';
import monitorServices from './service/monitor';
const { warning } = Modal;
// eslint-disable-next-line no-return-await
instanceRequest.reportCodeError = true;
const codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误), 或当前的会话已超时,请重新登录',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
export const SUCCESS_CODE = 0;
export const ERROR_CODE = -1;
let instance = null;
instanceRequest.setErrorHandler((error) => {
const { response } = error;
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, config } = response;
if (status === 401) {
if (!instance) {
instance = warning({
title: '错误信息',
content: `${codeMessage[status]}`,
centered: true,
onOk(close) {
window.share && window.share.event && window.share.event.emit('triggerLoginout');
close();
},
});
}
} else {
notification.error({
message: `请求错误 ${status}: ${config.url}`,
description: errorText,
});
}
} else if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
}
return response;
});
const monitorService = service(monitorServices);
export { monitorService };
import {request} from '@wisdom-utils/utils';
import * as constants from '../../constants';
const MonitorDevice = '/PandaMonitor/Monitor/Device';
const API = {
GET_ALARM_LIST_REAL_TIME: `${MonitorDevice}/GetAlarmListRealTime`,
GET_DEVICE_QUOTA_LIST: `${MonitorDevice}/GetQuotaList`, //
GET_EQUIPMENT_INFO: `${MonitorDevice}/GetEquipmentInfo`, // 获取设备树
};
const monitorServices = {
GetAlarmListRealTime: {
url: API.GET_ALARM_LIST_REAL_TIME, // 获取 数据维护日志
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
GetDeviceQuotaList: {
url: API.GET_DEVICE_QUOTA_LIST,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getEquipmentInfo: {
url: API.GET_EQUIPMENT_INFO,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
};
export default monitorServices;
export const SERVICE_APP_GET_UI_META = 'app.getUIMeta';
export const SERVICE_APP_LOGIN_MODE = {
password: 'password',
dingding: 'dingding',
weixin: 'weixin',
phone: 'phone',
};
export const LOGIN_DISPLAY = {
Account: 'Account',
WeChart: 'WeChart',
Mobile: 'Mobile',
};
export const LOGIN_WAY = {
Account: 'pdw',
WeChart: 'iotWechat',
Mobile: 'iotPhone',
};
export const WX_REDIRECT_URI = 'https://panda-water.com/civbase/user/login';
export const SERVICE_INTERFACE_SUCCESS_CODE = 0;
export const SERVICE_INTERFACE_PARAMS_EXCEPTION_CODE = -1; // 服务参数异常
export const SERVICE_INTERFACE_HANDLE_EXCEPTION_CODE = -2; // 服务处理异常
export const SERVICE_APP_CLOSE_ALL_TABS = 'app.close.tabs';
export const REQUEST_HTTP = 'http';
export const REQUEST_POP = 'pop';
export const REQUEST_METHOD_GET = 'get';
export const REQUEST_METHOD_POST = 'post';
export const REQUEST_METHOD_PUT = 'put';
export const REQUEST_METHOD_DELETE = 'delete';
import React from 'react';
import AlarmScrollAssembly from '../index';
window.globalConfig = {
userInfo: { OID: 1 },
};
export default () => {
return <AlarmScrollAssembly deviceType={'二供泵房,二供机组'} />; // 最小宽度930px
};
import React, { useState, useEffect, useRef } from 'react';
import styles from './index.less';
import PropTypes from 'prop-types';
import { Tag, Tooltip, Modal } from 'antd';
import { EnvironmentOutlined } from '@ant-design/icons';
import { monitorService } from './api';
import moment from 'moment';
import classnames from 'classnames';
import { switchTimeToPeriod } from './utils';
import NormChart from './NormChart/NormChart';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper.min.css';
import 'swiper/components/pagination/pagination.min.css';
import 'swiper/components/navigation/navigation.min.css';
import SwiperCore, { Autoplay, Pagination, Navigation } from 'swiper/core';
SwiperCore.use([Autoplay, Pagination, Navigation]);
/*
* 1. 获取当前所有数据;
* 2. 倒序滚动播放;
* 3. 初始化进入时,取截止到当前时间为止的所有的实时报警数据。
* 4. 播放结束后,重新获取实时报警数据进行第二轮的播放。
* */
const InfoItem = ({ info }) => {
const returnClassName = (type, key) => {
let _className = '';
if (type === '普通') {
_className = 'normal';
} else if (type === '紧急') {
_className = 'warning';
}
return `${_className}${key}`;
};
const { alertLevel, startTime, stationName, alertMsg, deviceAddress } = info;
return (
<div className={styles[returnClassName(alertLevel, 'Wrapper')]}>
<Tag className={styles[returnClassName(alertLevel, 'Tag')]}>{alertLevel}</Tag>
<span className={classnames(styles.time, styles.fontSize13)}>{startTime}</span>
<Tooltip title={deviceAddress} placement={'topLeft'}>
<span className={styles.location}>
<EnvironmentOutlined
style={{ fontSize: 12, color: '#666666', marginRight: 5, verticalAlign: 'middle' }}
/>
{deviceAddress}
</span>
</Tooltip>
<Tooltip title={alertMsg} placement={'topLeft'}>
<span className={styles[returnClassName(alertLevel, 'Content')]}>{alertMsg}</span>
</Tooltip>
<div className={styles.periodWrapper}>
<span className={styles.period}>{switchTimeToPeriod(startTime)}</span>
</div>
</div>
);
};
const AlarmScrollAssembly = (props) => {
const [modalVisible, setModalVisible] = useState(false);
const [currentInfo, setCurrentInfo] = useState({});
const constanceRef = useRef({
level: '1,2',
type: '直接取值,取变化量,取变化率,取是否',
userID: window.globalConfig.userInfo.OID,
userAccess: true,
});
const [realTimeDataList, setRealTimeDataList] = useState(null);
const getDeviceNumber = () => {
return monitorService.getEquipmentInfo({
deviceTypes: props.deviceType,
pageIndex: 1,
pageSize: 1,
...constanceRef.current,
});
};
const getRealTimeData = (pagination) => {
return monitorService.GetAlarmListRealTime({
deviceType: props.deviceType,
...constanceRef.current,
pageIndex: pagination.pageIndex,
pageSize: pagination.pageSize,
userAccess: props.userAccess === void 0 ? true : props.userAccess,
/* dateFrom: moment().subtract(1, 'days').format('YYYY-MM-DD 00:00:00'),
dateTo: moment().format('YYYY-MM-DD 23:59:59'),*/
});
};
const getData = async () => {
let firstRequest = await getDeviceNumber();
let secondRequest = await getRealTimeData({
pageIndex: 1,
pageSize: firstRequest.data.totalCount,
});
setRealTimeDataList(secondRequest.data.list);
};
useEffect(() => {
getData();
}, []);
return (
<div className={styles.alarScrollAssembly} id={'alarmListDiv'}>
{realTimeDataList && realTimeDataList.length ? (
<Swiper
slidesPerView={1}
modules={[Pagination]}
pagination={{
type: 'fraction',
formatFractionCurrent: (num) => `第${num}条`,
formatFractionTotal: (num) => `共${num}条`,
}}
navigation
autoplay={{
delay: 3000,
disableOnInteraction: false,
}}
loop
direction="vertical"
onSlideChange={(e) => {
if (e.activeIndex === realTimeDataList.length - 1) getData();
}}
>
{realTimeDataList.map((item, index) => {
return (
<SwiperSlide
key={index}
virtualIndex={index}
onClick={() => {
setCurrentInfo(item);
setModalVisible(true);
}}
>
<InfoItem key={index} info={item} />
</SwiperSlide>
);
})}
</Swiper>
) : (
''
)}
{modalVisible && (
<Modal
visible={modalVisible}
onCancel={() => setModalVisible(false)}
width={'80%'}
destroyOnClose
>
<NormChart
info={currentInfo}
deviceType={currentInfo.deviceType}
deviceCode={currentInfo.stationCode}
/>
</Modal>
)}
</div>
);
};
AlarmScrollAssembly.defaultProps = {
deviceType: '二供泵房,二供机组',
};
AlarmScrollAssembly.propTypes = {
deviceType: PropTypes.string,
};
export default AlarmScrollAssembly;
.alarScrollAssembly {
:global {
.swiper-container {
width: 950px;
height: 42px;
.swiper-button-prev {
right: 150px;
left: auto !important;
}
.swiper-button-next:after,
.swiper-button-prev:after {
font-size: 12px;
}
.swiper-pagination-fraction {
top: 15px;
right: 24px;
left: auto;
width: 130px;
line-height: 12px;
}
.swiper-wrapper {
width: calc(100% - 140px);
}
.swiper-slide {
height: 32px;
line-height: 32px;
text-align: center;
}
}
}
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
min-width: 930px;
height: 42px;
overflow-y: scroll;
.warningWrapper {
display: flex;
align-items: center;
max-width: 760px;
padding: 4px 12px;
background: #ffeeee;
border: 1px solid #ffceca;
border-radius: 3px;
}
.normalWrapper {
display: flex;
align-items: center;
max-width: 760px;
padding: 4px 12px;
background: #fffbeb;
border: 1px solid #ffd9a7;
border-radius: 3px;
}
.warningTag {
color: #ffffff;
background: linear-gradient(180deg, #f98b5e 0%, #f44545 100%);
border: none !important;
}
.normalTag {
color: #ffffff;
background: linear-gradient(180deg, #ffbf11 0%, #ff9c00 100%);
border: none !important;
}
.fontSize13 {
font-size: 13px;
}
.time {
display: inline-block;
width: 120px;
color: #333333;
}
.location {
display: inline-block;
//flex: 230;
//width: 230px;
//min-width: 100px;
flex: 1;
align-items: center;
margin-left: 14px;
overflow: hidden;
color: #333333;
white-space: nowrap;
text-overflow: ellipsis;
}
.periodWrapper {
display: flex;
align-items: center;
justify-content: right;
max-width: 190px;
.period {
display: inline-block;
width: 120px;
margin-left: 10px;
color: #333333;
}
}
.normalContent {
display: inline-block;
flex: 2;
margin-left: 14px;
overflow: hidden;
//width: 290px;
color: #fe7200;
white-space: nowrap;
text-overflow: ellipsis;
}
.warningContent {
display: inline-block;
flex: 2;
margin-left: 14px;
overflow: hidden;
//width: 290px;
color: #ff2929;
white-space: nowrap;
text-overflow: ellipsis;
}
}
import moment from 'moment';
export const switchTimeToPeriod = (time) => {
if (!time) return '';
let _day = 0;
let _hour = 0;
let _minutes = 0;
_day = moment().diff(moment(time), 'days');
_hour = moment().diff(moment(time), 'hours');
_minutes = moment().diff(moment(time), 'minutes');
return (
`${_day ? _day + '天' : ''}${_hour ? _hour - _day * 24 + '小时' : ''}${
_minutes ? _minutes - _hour * 60 + '分钟' : ''
}` || '刚刚'
);
};
......@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.5.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicchart@1.4.3...@wisdom-components/basicchart@1.5.0) (2022-12-30)
### Features
- 更新图表样式设置 ([17390a0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/17390a009d7f9bf918211b77b9b93efe64f8f257))
## [1.4.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicchart@1.4.2...@wisdom-components/basicchart@1.4.3) (2022-12-19)
### Bug Fixes
......
{
"name": "@wisdom-components/basicchart",
"version": "1.4.3",
"version": "1.5.0",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
......
......@@ -17,13 +17,12 @@ const ECharts = memo(
// const chartProps = pick(props, ['option', 'notMerge', 'lazyUpdate', 'style', 'className', 'theme', 'onChartReady', 'loadingOption', 'showLoading', 'onEvents', 'opts']);
console.log('update ');
return (
<ReactEcharts
ref={ref}
className={classNames(prefixCls, props.className)}
option={option}
style={{width: '100%',height:'100%'}}
{...chartProps}
/>
);
......
# Change Log
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.9.0 (2022-12-22)
### Features
- 提交报表代码 ([48ac121](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/48ac1217adf2d9365bab135764c8a3a6039c3d49))
## [1.8.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.8.0...@wisdom-components/basicreport@1.8.2) (2022-12-13)
### Bug Fixes
- 修复函数未引用导致的 bug ([3f3eb57](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3f3eb57d01d9d97a0e1c5b836cef09e93d1193b1))
- 修复函数未引用导致的 bug ([07038a2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/07038a22afd57b8935ea6cdb6c3fd761f14f3ff0))
## [1.8.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.8.0...@wisdom-components/basicreport@1.8.1) (2022-12-13)
### Bug Fixes
- 修复函数未引用导致的 bug ([07038a2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/07038a22afd57b8935ea6cdb6c3fd761f14f3ff0))
# [1.8.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.7.0...@wisdom-components/basicreport@1.8.0) (2022-12-07)
### Features
- 更新轻量化报表 ([3985ad9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3985ad9af1a9d3130ad07eab0cb959a820a73fad))
# [1.7.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.6.0...@wisdom-components/basicreport@1.7.0) (2022-12-07)
### Features
- 更新轻量化报表功能 ([d73f0e6](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/d73f0e6c84d5633af7cfe3d4bf3c234bcaa8f2c9))
# [1.6.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.5.0...@wisdom-components/basicreport@1.6.0) (2022-09-13)
### Features
- 更新 baiscreport 版本 ([fa63f24](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/fa63f244ddcc23f4fe11dd78acd8d9fcc8b3cc8a))
- 优化默认筛选值的逻辑,现在可以配置多个筛选值 ([62f7fed](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/62f7fed834d31526b8fb33868fad905bf45de4fc))
# [1.5.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.4.0...@wisdom-components/basicreport@1.5.0) (2022-09-13)
### Features
- 实现选择器 ([9df6ec8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/9df6ec87a429fe9c8d321a6f7bc4a5677b852b7f))
# [1.4.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.3.1...@wisdom-components/basicreport@1.4.0) (2022-09-07)
### Bug Fixes
- 修复组件引入错误 ([31facdf](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/31facdf92b6200c3ceac31fb549a77faa4a68434))
### Features
- 新增 demo ([0ffab69](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/0ffab69ab677d377ce861e1ab9205ab8b78464a4))
## [1.3.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.3.0...@wisdom-components/basicreport@1.3.1) (2022-09-06)
### Bug Fixes
- 修复路径错误 ([c7d8fa8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/c7d8fa8230f1f47478010e8e1263b1aa46703311))
# [1.3.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.3...@wisdom-components/basicreport@1.3.0) (2022-09-05)
### Features
- 新增大量功能 ([437dd7c](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/437dd7ca8cb83552b88e11585bb9b7040ee6b07e))
## [1.2.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.2...@wisdom-components/basicreport@1.2.3) (2022-08-29)
### Bug Fixes
- 兼容日期为 null 的情况 ([0ef2dfb](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/0ef2dfb65a938134d8ecea589479ccc99c7c7b93))
## [1.2.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.1...@wisdom-components/basicreport@1.2.2) (2022-08-18)
### Bug Fixes
- fix ([bc49887](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/bc498875cbd3deb3104ff5d61c99cb3c318ba355))
## [1.2.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.0...@wisdom-components/basicreport@1.2.1) (2022-08-18)
### Bug Fixes
- 修复数据格式导致的报错;修复路径引入导致的报错 ([6014c40](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/6014c40b6b19f9060b69e95ce729dcdfc2935521))
# [1.2.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.3...@wisdom-components/basicreport@1.2.0) (2022-08-18)
### Features
- 重新处理报表逻辑 ([3ebe719](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3ebe71907d0b60988a53c7b641189f748490826b))
## [1.1.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.2...@wisdom-components/basicreport@1.1.3) (2022-08-17)
### Bug Fixes
- 重新发布 ([2776cf9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/2776cf9dd8f7520a84c00fad5500da38ec42dc8f))
## [1.1.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.1...@wisdom-components/basicreport@1.1.2) (2022-08-17)
### Bug Fixes
- 删除无效引用 ([372c06f](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/372c06f3233ab5e48d6b104addfb6ba95e43d847))
## [1.1.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.0...@wisdom-components/basicreport@1.1.1) (2022-08-17)
### Bug Fixes
- 修复文件引用错误 ([7e486a8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7e486a8a6c321fd36d89e78975c4e65002f7eaa2))
# 1.1.0 (2022-08-17)
### Features
- 新增报表组件 ([561f975](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/561f975db85081d678854c94e859406903f71438))
- 新增 BasicReport ([fb2e80f](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/fb2e80f00b130f48e743de5dd4781913e7ff4c01))
- 增加 package.json ([e10973a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e10973a31059ceab4b2e01dda56fdd54ade270bc))
{
"name": "@wisdom-components/basicreport",
"version": "1.9.0",
"description": "> TODO: description",
"author": "chenlong <857265978@163.com>",
"homepage": "",
"license": "ISC",
"sideEffects": [
"*.less"
],
"module": "es/index.js",
"main": "es/index.js",
"files": [
"lib",
"es",
"dist"
],
"directories": {
"lib": "lib",
"es": "es",
"dist": "dist",
"test": "__tests__"
},
"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"
},
"dependencies": {
"@babel/runtime": "^7.17.9",
"@wisdom-components/basictable": "^1.5.25"
}
}
#### 常规使用
<code src="./demos/Basic.tsx">
// 文本/下拉/多选/时间
/**
* @description:
* @params:
* onChange: 需要传入onChange,接收值的变更
*/
import React, { useEffect, useState } from 'react';
import { Input, Select } from 'antd';
import { reportService } from '../../api';
import { returnDefaultValueOrConfigs } from '../utils/utils';
const { Option } = Select;
const { Search } = Input;
const USER_ID = window.globalConfig.userInfo.OID;
const TextSearchComponent = ({ onChange, style, onSearch, placeholder }) => {
return (
<Search
title={placeholder}
style={style}
placeholder={placeholder}
onChange={onChange}
onSearch={onSearch}
/>
);
};
/**
* Data = ['选项1','选项2'...]
*
* @props:
* 正常选项:武汉
* 附带统计数值: 武汉 (20)
*/
const SelectSearchComponent = ({
onChange,
style,
data,
mode,
reportName,
fieldAlias,
configItems,
filterFields,
filterValues,
filterObject,
}) => {
const [value, setValue] = useState('');
const [options, setOptions] = useState([]);
const defaultConfigs = returnDefaultValueOrConfigs(configItems, ['defaultValue']);
const { defaultValue } = defaultConfigs;
const getData = () => {
reportService
.getReportFilterValues({
fieldAlias,
...filterObject,
})
.then((res) => {
if (res.code === 0) {
let _options = res.data
.find((item) => item.fieldAlias === fieldAlias)
.filterValues.filter((item) => item.filterValue);
if (filterValues && filterFields) {
let _filterFields = filterFields.split('|');
let _filterValues = filterValues.split('|');
let _index = _filterFields.findIndex((item) => item === fieldAlias);
if (_index > -1) {
let _needToFilterValues = _filterValues[_index]?.split(',') || [];
_options = _options.filter((item) => _needToFilterValues.includes(item.filterValue));
}
}
setOptions(_options);
}
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getData();
setValue(defaultValue);
}, []);
return (
<Select
value={value}
style={style}
onChange={(e) => {
onChange(e);
setValue(e);
}}
mode={mode}
defaultValue={mode === 'multiple' && defaultValue ? defaultValue.split(',') : defaultValue}
allowClear
maxTagCount={1}
placeholder={`请选择${fieldAlias}`}
>
{options && options.length
? options.map((item) => (
<Option key={item.filterValue} value={item.filterValue}>
{item.filterValue} <span style={{ color: 'rgba(0,0,0,.65)' }}>({item.count})</span>
</Option>
))
: ''}
</Select>
);
};
const ReturnControlComponent = ({
type,
onChange,
style,
data,
onSearch,
reportName,
fieldAlias,
placeholder,
configItems,
filterValues,
filterFields,
filterObject,
}) => {
let _component = '';
switch (type) {
case '文本':
_component = (
<TextSearchComponent
style={style}
onChange={onChange}
onSearch={onSearch}
placeholder={placeholder}
configItems={configItems}
/>
);
break;
case '下拉':
case '多选':
_component = (
<SelectSearchComponent
mode={type === '多选' ? 'multiple' : ''}
style={style}
onChange={onChange}
reportName={reportName}
fieldAlias={fieldAlias}
configItems={configItems}
filterFields={filterFields}
filterValues={filterValues}
filterObject={filterObject}
/>
);
break;
default:
break;
}
return _component;
};
export default ReturnControlComponent;
/*
** 自定义取色板
** create by ChenLong on 2022/8/23
** 功能路径:src\pages\product\ReportsManage\Components\CustomerColorPicker.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/
import React from 'react';
import style from './CustomerColorPicker.less';
import { tagColors, tagBackgroundColors } from '../../utils/constant';
import classnames from 'classnames';
const CustomerColorPicker = (props) => {
return (
<div className={style.colorPickerWrapper}>
{tagColors.map((color, index) => (
<div
className={classnames(style.colorCard)}
onClick={() => props.clickColorPicker(tagBackgroundColors[index])}
style={{
color: color,
backgroundColor: tagBackgroundColors[index],
}}
>
A
</div>
))}
</div>
);
};
export default CustomerColorPicker;
@import '~antd/es/style/themes/default.less';
.colorPickerWrapper {
display: flex;
gap: 5px;
width: 330px;
//height: 40px;
padding: 10px;
background: #ffffff;
border: 1px solid rgba(200, 200, 200, 0.85);
border-radius: 4px;
.colorCard {
display: flex;
flex: 0 0 30px;
align-items: center;
justify-content: center;
height: 30px;
font-size: 14px;
&:hover {
font-weight: bold;
font-size: 16px;
box-shadow: #1685ff;
cursor: pointer;
}
}
}
/** @tips: 约定:该控件,获取文件路径字符串或上传了文件(即对应编辑时从接口获取的文件链接和新增时获取的对象),都会将符合要求的对象(上传的文件数据或自行拼接的,必须包含status、type、uid等必要字段)转化为字符串 */
/**
* @description: 合并老版的文件、可预览文件、录音、视频
* @params: 接收参数 renderTo: Recording/Video/File
* @return: {Object} 文件类型返回需要另外处理
* @date: 2021/12/1
* @author: ChenLong
* @待解决问题: 为什么list不直接返回url,而要把file对象变成对象字符串?
*/
/** @tips: 上传业务为:1.通过上传接口,上传文件,获取上传的链接;2.将文件链接存储到服务器,获取存储的地址;3.提交地址 */
/**
* @description: 完成 1.文件名校验;2.编辑界面的文件加载及显示的能力;3.不同类型文件的判断
* @date: 2021/12/2
*/
/**
* @description: 合并图片/可预览图片到文件上传中
* @date: 2021/12/6
*/
/**
* @description: 文件类型单独处理。文件类型返回的是文件对象的字符串,使用JSON.parse解析之后,取url值即可,拼成用逗号分割的字符串即可。这部分修改在入口文件内
* @description: 需要判断值是文件对象的字符串,约定:文件类必须会有 status: 'done'
* @date: 2021/12/8
*/
/** @tips: 裁剪功能在前端框架内无法正常工作,暂不提供裁剪功能 */
// 自定义Form Render组件
import React, { useState, useEffect } from 'react';
import { Upload, Button, Modal, message } from 'antd';
import { UploadOutlined, DownloadOutlined } from '@ant-design/icons';
import './fileUpload.less';
import { downloadFunc, filenameVerification } from '../../utils/utils';
import { uploadFileUrl, downloadFileUrl } from '../../../api/service/workflow';
const videoTypeArray = ['.mp4'];
const audioTypeArray = ['.mp4'];
const fileTypeArray = [];
const imageTypeArray = ['.bmp', '.gif', '.jpeg', 'tiff', '.png', '.svg', '.jpg'];
const FileUpload = ({ value, onChange, schema }) => {
const _isRecordingOrVideo = ['Recording', 'Video', 'Image'].includes(schema.renderTo);
const _isVideo = schema.renderTo === 'Video';
const _isAudio = schema.renderTo === 'Recording';
const _isImage = schema.renderTo === 'Image';
const [previewTitle, setPreviewTitle] = useState('');
const [previewVisible, setPreviewVisible] = useState(false);
const [previewUrl, setPreviewUrl] = useState('');
const [showList, setShowList] = useState('');
const file = value || schema.default;
const option = {
name: 'file',
action: `${window.location.origin}${uploadFileUrl}`,
listType: _isRecordingOrVideo ? 'picture-card' : 'picture',
withCredentials: true,
beforeUpload(file, fileList) {
/** @tips: 解决提交文件中存在特殊字符的问题 */
let _continueUpload = true;
let _msg = {
type: 'success',
content: '上传成功!',
};
fileList.forEach((item) => {
let _msgObject = filenameVerification(item);
if (_msgObject.type === 'error') {
_continueUpload = false;
_msg = {
type: 'error',
content: '上传失败!文件名不符合规则!',
};
}
});
_msg.type === 'error' ? message[_msg.type](_msg.content) : '';
return _continueUpload;
},
onChange: ({ file, fileList, event }) => {
// 检验名字,名字不通过不允许显示
if (filenameVerification(file).type === 'error') return false;
// 返回的链接在file.response内;不设置url,预览图表不可点击
if (file.status === 'done' && file.response.code === 0) {
file.url = `${downloadFileUrl}?filePath=${file.response.data}`;
file.sourcePath = file.response.data;
message.success('上传成功!');
} else if (file.status === 'done' && file.response.code !== 0) {
file.status = 'error';
message.error('上传失败!');
}
onChange((fileList && fileList.length && JSON.stringify(fileList)) || '');
setShowList(JSON.stringify(fileList));
},
onPreview(file) {
if (_isRecordingOrVideo) {
setPreviewVisible(true);
setPreviewUrl(file.url);
}
},
previewFile(file) {},
onDownload(file) {
downloadFunc(file.url, file.name, '_self');
},
};
const handleCancel = () => {
setPreviewVisible(false);
setPreviewTitle('');
};
/**
* @description: 返回文件类型限定值
* @params: {Array} typeArray: Video | Recording | File
* @date: 2021/12/2
* @author: ChenLong
*/
const returnFileTypeString = (type) => {
let _obj = {
Video: videoTypeArray,
Recording: audioTypeArray,
File: fileTypeArray,
Image: imageTypeArray,
};
return _obj[type].join(',');
};
useEffect(() => {
let fileList = [];
(file || '').split(',').forEach((item, index) => {
if (item && filenameVerification({ name: item }, true).type !== 'error') {
// @Tips: 直接过滤掉名字中有异常字符的文件
let _obj = {
uid: index + '_' + Math.random(),
value: item,
name: item.split('\\').reverse()[0],
type: schema.renderTo === 'Image' ? 'image' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}`,
sourcePath: item,
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
fileList.push(_obj);
}
});
// onChange(fileList.length && JSON.stringify(fileList) || '');
setShowList(JSON.stringify(fileList));
}, []);
useEffect(() => {
if (value) {
let fileList = [];
(file || '').split(',').forEach((item, index) => {
if (item && filenameVerification({ name: item }, true).type !== 'error') {
// @Tips: 直接过滤掉名字中有异常字符的文件
let _obj = {
uid: index + '_' + Math.random(),
value: item,
name: item.split('\\').reverse()[0],
type: schema.renderTo === 'Image' ? 'image' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}`,
sourcePath: item,
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
fileList.push(_obj);
}
});
// onChange(fileList.length && JSON.stringify(fileList) || '');
setShowList(JSON.stringify(fileList));
}
}, [value]);
return (
<>
{/** @tips: 裁剪功能无法正常工作,暂不提供 */}
{/* <ImgCrop beforeCrop={(file) => {
let _returnObj = filenameVerification(file);
if (_returnObj.type === 'error') {
message.error(_returnObj.content);
return false;
}
return schema.renderTo === 'Image';
}} rotate locale={'zh-cn'} modalTitle={'编辑图片'} modalOk={'确定'}
modalCancel={'取消'}>*/}
<Upload
disabled={schema.disabled}
{...option}
fileList={showList ? JSON.parse(showList) : []}
multiple
style={{ width: '100%' }}
className={_isRecordingOrVideo ? 'formUploadVideoOrRecording' : 'formUpload'}
showUploadList={{
showPreviewIcon: _isRecordingOrVideo,
showDownloadIcon: true,
downloadIcon: <DownloadOutlined />,
}}
accept={returnFileTypeString(schema.renderTo)}
>
{!_isRecordingOrVideo ? (
<Button disabled={schema.disabled} icon={<UploadOutlined />}>
Upload
</Button>
) : (
'+ Upload'
)}
</Upload>
{/* </ImgCrop>*/}
<Modal
style={{ width: '30%' }}
bodyStyle={{ textAlign: 'center' }}
visible={previewVisible}
title={previewTitle}
footer={null}
onCancel={handleCancel}
>
{_isVideo ? (
<video width={'100%'} height={'100%'} controls autoPlay src={previewUrl} />
) : (
''
)}
{_isAudio ? <audio controls autoPlay src={previewUrl} /> : ''}
{_isImage ? <img width={'100%'} height={'100%'} src={previewUrl} alt="缩略图" /> : ''}
</Modal>
</>
);
};
export default FileUpload;
@import '~antd/es/style/themes/default.less';
@parse-form-prefix-cls: ~'@{ant-prefix}-parse-form';
.@{parse-form-prefix-cls} {
.formUpload {
width: 100%;
.@{ant-prefix}-upload-list-item {
float: left;
width: 49%;
max-width: 300px; // 增加了最大宽度,防止样式失效导致布局错误的问题
margin-right: 1%;
}
}
.@{ant-prefix}-animate {
}
.formUploadVideoOrRecording {
width: 100%;
.@{ant-prefix}-upload-list-item {
float: left;
width: 99%;
margin-right: 1%;
}
}
}
/*
** 报表的编辑、新增表单
** create by ChenLong on 2022/8/10
** 功能路径:src\pages\product\ReportsManage\ReportEditForm.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/
import React, { useEffect, useState, useContext } from 'react';
import {
Form,
Input,
DatePicker,
InputNumber,
Row,
Col,
Button,
message,
Select,
ConfigProvider,
} from 'antd';
import moment from 'moment';
import { submitReportData } from '../api/service/report';
import FileUpload from './Components/fileUpload/fileUpload';
import { reportService } from '../api';
import { isSelect, returnOptions, returnRows, returnCols } from './utils/utils';
import style from './ReportEditForm.less';
const { Option } = Select;
const { TextArea } = Input;
// 类型
const USER_ID = window.globalConfig.userInfo.OID;
const TEXT_ARRAY = ['文本', '标签'];
const TEXTAREA_ARRAY = ['多行文本'];
const DATE_PICKER_ARRAY = ['日期'];
const DATE_TIME_PICKER_ARRAY = ['日期时刻'];
const DATE_TYPE = ['日期', '日期时刻']; // 用来匹配是否需要转为日期对象;
const NUMBER_ARRAY = ['数值', '数值标签'];
const FILE_ARRAY = ['附件'];
// 形态对应组件
// 对应关系
/**
* @description: 函数描述
* @date: 2022/8/10
* @author: ChenLong
* @params: reportDetails 各个字段的配置列表
* data 与reportDetails对应的值
*/
const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName, modalType }) => {
// if (!reportData || Object.keys(reportData).length === 0) return <>未传递表单数据</>;
const [fileAlias, setFileAlias] = useState([]); // 附件需要单独处理提交的数据
const [form] = Form.useForm();
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls();
/* const formItemLayout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};*/
// 数值类的后端会处理再返回,故无序处理精度问题
const handleDate = (reportDetails, data) => {
let _data = { ...data };
reportDetails.forEach((item) => {
if (DATE_TYPE.includes(item.type)) {
_data[item.fieldAlias] = data[item.fieldAlias] ? moment(data[item.fieldAlias]) : moment();
}
});
return _data;
};
const componentMap = (config) => {
if (DATE_TIME_PICKER_ARRAY.includes(config.type)) {
return <DatePicker showTime readonly={config.isReadOnly} />;
} else if (DATE_PICKER_ARRAY.includes(config.type)) {
return <DatePicker disabled={config.isReadOnly} />;
} else if (NUMBER_ARRAY.includes(config.type)) {
return <InputNumber disabled={config.isReadOnly} />;
} else if (FILE_ARRAY.includes(config.type)) {
return <FileUpload schema={{ renderTo: 'File' }} disabled={config.isReadOnly} />;
} else if (TEXTAREA_ARRAY.includes(config.type)) {
let _rows = returnRows(config.configItems);
return <TextArea rows={_rows} disabled={config.isReadOnly} />;
} else {
if (isSelect(config.configItems)) {
let options = returnOptions(config.configItems);
if (options) {
return (
<Select disabled={config.isReadOnly}>
{options.map((item) => (
<Option value={item}>{item}</Option>
))}
</Select>
);
}
}
return <Input disabled={config.isReadOnly} />;
}
};
const submitReportForm = () => {
form.validateFields().then((values) => {
let _data = values;
let final = [];
Object.keys(_data).forEach((key) => {
let value = reportData[key];
let _value = _data[key];
if (moment.isMoment(_data[key])) {
_value = moment(_data[key]).format('YYYY-MM-DD HH:mm:ss');
}
if (value !== _value) {
if (fileAlias.includes(key)) {
_value = _value
? JSON.parse(_value)
.reduce((final, curr) => {
final.push(curr.sourcePath);
return final;
}, [])
.join(',')
: '';
}
let _finalData = {
fieldAlias: key,
fieldValue: _value,
};
if (modalType === '编辑') {
_finalData.key = reportData.Key;
}
final.push(_finalData);
}
});
if (modalType === '新增') {
reportService
.addReportData({
reportName: reportName,
userId: USER_ID,
reportDatas: final,
})
.then((res) => {
if (res.code === 0) {
message.success('保存成功!');
onCancel();
} else if (res.code === -1) {
message.error(res.msg);
} else if (res.code === -2) {
message.error('系统故障,请找管理员查看故障!');
}
});
}
if (modalType === '编辑') {
submitReportData(
{},
{
editDatas: final,
reportName: reportName,
userId: USER_ID,
},
).then((res) => {
if (res.code === 0) {
message.success('保存成功!');
onCancel();
} else if (res.code === -1) {
message.error(res.msg);
} else if (res.code === -2) {
message.error('系统故障,请找管理员查看故障!');
}
});
}
});
};
useEffect(() => {
if (reportDetails && reportDetails.length) {
let _fileAlias = [...fileAlias];
reportDetails.forEach((item) => {
if (item.type === '附件') _fileAlias.push(item.fieldAlias);
});
setFileAlias(_fileAlias);
}
}, [reportDetails]);
useEffect(() => {
if (reportData && Object.keys(reportData).length)
form.setFieldsValue(handleDate(reportDetails, reportData));
}, [reportData]);
return (
<div className={style.reportEditForm} style={{ position: 'relative' }}>
<div>
<Form form={form}>
<Row style={{ overflowY: 'scroll', maxHeight: 'calc(100vh - 300px)' }}>
{reportDetails &&
reportDetails
.filter((config) => {
if (modalType === '新增' && config.isReadOnly) return false;
return config;
})
.map((config) => {
// return <Col span={returnCols(config.configItems) * 8} key={config.fieldAlias}>
return (
<div
style={{ width: `${returnCols(config.configItems) * 33.3}%` }}
key={config.fieldAlias}
>
<Form.Item
label={config.fieldAlias}
name={config.fieldAlias}
rules={[
{
required: config.isRequired,
message: `${config.fieldAlias}必填`,
},
]}
>
{componentMap(config)}
</Form.Item>
</div>
);
})}
</Row>
<Row>
<Col span={24} style={{ textAlign: 'right' }}>
{/*<Form.Item style={{textAlign:'right'}}>*/}
<Button
style={{ position: 'sticky', bottom: 0 }}
type={'primary'}
onClick={submitReportForm}
>
提交
</Button>
{/*</Form.Item>*/}
</Col>
</Row>
</Form>
</div>
</div>
);
};
export default ReportEditForm;
@import '~antd/es/style/themes/default.less';
.reportEditForm {
:global {
.@{ant-prefix}-form-item-label {
width: 120px !important;
}
input[disabled] {
background-color: rgb(250, 250, 250);
cursor: default;
}
// 多行文本框
.@{ant-prefix}-input[disabled] {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
border-color: #d9d9d9;
box-shadow: none;
cursor: default;
opacity: 1;
}
// 时间选择器的disabled样式
.@{ant-prefix}-picker-disabled {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
cursor: default;
& + span {
cursor: default;
}
}
// radio的disabled样式
.@{ant-prefix}-radio-disabled {
cursor: default;
& + span {
cursor: default;
}
.@{ant-prefix}-radio-inner {
cursor: default;
}
}
// 下拉选已选的disabled样式
.@{ant-prefix}-cascader-picker-disabled {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
cursor: default;
}
// 按钮的disabled样式
.@{ant-prefix}-btn[disabled] {
text-shadow: none;
background: #ffffff;
border-color: #d9d9d9;
box-shadow: none;
cursor: default;
&:hover,
&:focus,
&:active {
color: rgba(0, 0, 0, 0.25);
text-shadow: none;
background: #ffffff;
border-color: #d9d9d9;
box-shadow: none;
}
}
// 多选下的tag的disabled样式
.@{ant-prefix}-select-disabled.@{ant-prefix}-select-multiple {
.@{ant-prefix}-select-selection-item {
color: #bfbfbf;
border-color: #d9d9d9;
cursor: default;
}
}
.@{ant-prefix}-select-disabled.@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input) {
.@{ant-prefix}-select-selector input {
cursor: default;
}
}
// 时间选择框
.@{ant-prefix}-picker-input > input[disabled] {
color: rgba(0, 0, 0, 0.85);
}
}
}
@import '~antd/es/style/themes/default.less';
.reportsDataSourceSetting {
height: 100%;
overflow: hidden;
.contentWrapper {
display: flex;
flex-direction: column;
height: calc(100% - 16px);
margin: 8px;
@media screen and (min-width: 1680px) {
.content {
grid-template-columns: repeat(5, 1fr);
}
}
@media screen and (max-width: 1680px) {
.content {
grid-template-columns: repeat(4, 1fr);
}
}
@media screen and (max-width: 1320px) {
.content {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (max-width: 960px) {
.content {
grid-template-columns: repeat(2, 1fr);
}
}
.controlRow {
display: flex;
flex-direction: column;
margin-bottom: 8px;
padding: 8px;
background: #ffffff;
:global {
.@{ant-prefix}-form-item {
margin-bottom: 0;
}
}
}
.content {
display: grid;
grid-gap: 10px;
padding-bottom: 8px;
overflow: scroll;
.card {
height: 198px;
.cardInfo {
padding-left: 48px;
.cardInfoItem {
margin-bottom: 4px;
color: rgb(100, 100, 100, 0.65);
.item {
color: rgba(58, 58, 58, 0.55);
font-weight: bold;
}
.blue {
color: rgba(23, 130, 252, 0.65);
}
.ellipsis {
display: inline-block;
max-width: 120px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: top;
}
}
}
}
}
}
}
@import '~antd/es/style/themes/default.less';
.lackParams {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.reportManage {
display: flex;
flex-direction: column;
height: 100%;
padding: 8px;
.contentWrapper {
display: flex;
flex-direction: column;
height: 100%;
.controlRow {
display: flex;
flex-direction: row;
margin-bottom: 4px;
padding: 6px;
background: #ffffff;
border-radius: 4px;
}
.tableContent {
flex: 1;
padding: 6px;
background: #ffffff;
.handleColumnWrapper {
display: flex;
justify-content: space-around;
.editButton {
cursor: pointer;
&:hover {
color: rgb(24, 144, 255);
}
}
.deleteButton {
color: rgb(255, 0, 0);
cursor: pointer;
&:hover {
//color: rgb(24, 144, 255);
}
}
}
.spinWrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 60vh;
}
:global {
.@{ant-prefix}-table-container {
height: 100%;
& > .@{ant-prefix}-table-body {
border-right: 1px solid #dbe7fb;
border-bottom: 1px solid #dbe7fb;
}
.@{ant-prefix}-table-body {
flex: 1;
}
.@{ant-prefix}-table-summary > table > tfoot > tr > td {
border-right: none;
}
.@{ant-prefix}-table-summary > table > tfoot > tr:not(:last-child) > td {
border-bottom: none;
}
.@{ant-prefix}-table-summary > table > tfoot > tr:last-child > td {
border-bottom: 1px solid #dbe7fb;
}
}
.@{ant-prefix}-basic-table .@{ant-prefix}-pagination {
border-top: none;
}
}
}
}
.link {
cursor: pointer;
&:hover {
//color: #1685FF;
font-weight: bold;
text-decoration: underline;
}
}
:global {
.@{ant-prefix}-form-item {
margin-bottom: 0 !important;
}
}
.prefixOrSuffix {
color: rgba(0, 0, 0, 0.65);
font-size: 10px;
}
:global {
::-webkit-scrollbar,
*::-webkit-scrollbar {
width: 0px;
height: 6px;
}
::-webkit-scrollbar-track,
*::-webkit-scrollbar-track {
background: #f2f2f2;
border-radius: 10px;
}
::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-thumb {
background: #dcdcdc;
border-radius: 5px;
}
}
}
import React from 'react';
import ReportsManage from './ReportsManage';
const ReportsPermissionDelete = (props) => <ReportsManage {...props} state="delete" />;
export default ReportsPermissionDelete;
import React from 'react';
import ReportsManage from './ReportsManage';
const ReportsPermissionScan = (props) => <ReportsManage {...props} state="scan" />;
export default ReportsPermissionScan;
@import '~antd/es/style/themes/default.less';
.reportSettings {
//width: 100%;
height: 100%;
.reportFiled {
display: inline-block;
width: 100%;
overflow: hidden;
line-height: 1;
white-space: nowrap;
text-overflow: ellipsis;
&:hover {
color: #1685ff;
}
}
.reportDetails {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
padding: 8px;
.colorSketch {
position: absolute;
z-index: 1001;
width: 100%;
height: 100%;
}
:global {
.@{ant-prefix}-form-item {
margin-bottom: 0 !important;
}
}
.tableWrapper {
display: flex;
flex: 1;
flex-direction: column;
overflow: hidden;
.controlRow {
display: flex;
flex: 0 0 44px;
//justify-content: space-between;
align-items: center;
height: 44px;
margin-bottom: 4px;
padding: 6px;
background: #ffffff;
.leftBtn {
margin-right: 10px;
font-weight: bold;
font-size: 18px;
cursor: pointer;
&:hover {
color: #1685ff;
opacity: 0.8;
}
}
}
.tableContent {
flex: 1;
width: 100%;
max-height: calc(100% - 44px);
padding: 6px;
overflow: hidden;
background: #ffffff;
.tableForm {
height: 100%;
}
}
}
}
}
.boxShadow {
border-color: #40a9ff;
border-right-width: 1px;
outline: 0;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.boxShadowOfSwitch {
border-right-width: 1px;
outline: 0;
box-shadow: 0 0 4px 2px rgba(24, 144, 255, 0.6);
}
.boxShadowOfSelect {
border-right-width: 1px;
outline: 0;
box-shadow: 0 0 2px 2px rgba(24, 144, 255, 0.2);
:global {
.@{ant-prefix}-select-selector {
border-color: #40a9ff !important;
}
}
}
.fieldList {
cursor: pointer !important;
&:hover {
color: #1685ff;
}
&.active {
color: #1685ff;
}
}
packages/base-components/BasicReport/src/ReportsManage/assets/mysql.png

18 KB

File added
packages/base-components/BasicReport/src/ReportsManage/assets/sqlserver.png

33.9 KB

packages/base-components/BasicReport/src/ReportsManage/assets/webapi.png

13.7 KB

/**
* * 用来动态加载配置的组件功能函数 * create by ChenLong on 2022/7/28 * @Params: url 功能路径,加载需要的业务组件 * onCancel
* 从详情组件回到当前功能的函数 * params 其他的必要参数 * 功能路径:src\pages\product\ReportsManage\extra\detailsComponent.js
* * 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
*/
import React from 'react';
import { Button } from 'antd';
const DetailsComponent = ({ url, onCancel, params }) => {
/* const BusinessComponent = React.lazy(() => import(`@/pages/${url}`));
return <BusinessComponent onCancel={onCancel} {...params} />;*/
return <div>弹窗组件在组件中未实现</div>;
};
export default DetailsComponent;
// import AccountPermissionScan from '../../AccountManage/AccountPermissionScan';
import React from 'react';
import pic from '../assets/pic.webp';
const extraComponents = {
renderAccount: (props) => {
return <div>台账组件</div>;
},
returnImage: (data) => {
return <img width={200} height={200} src={pic} alt={data.alt} />;
},
default: () => <span>若需要使用弹窗功能,请开发或配置功能函数</span>,
};
export default extraComponents;
import MySQLIcon from '../assets/mysql.png';
import SQLServerIcon from '../assets/sqlserver.png';
import WebAPIIcon from '../assets/webapi.png';
const tagColors = [
'rgb(129, 134, 143)',
'rgb(41, 114, 244)',
'rgb(0, 163, 245)',
'rgb(69, 176, 118)',
'rgb(222, 60, 54)',
'rgb(248, 136, 37)',
'rgb(189, 160, 20)',
'rgb(154, 56, 215)',
'rgb(221, 64, 151)',
];
const tagBackgroundColors = [
'rgb(220, 223, 228)',
'rgb(214, 229, 255)',
'rgb(214, 241, 255)',
'rgb(211, 243, 226)',
'rgb(255, 220, 219)',
'rgb(255, 236, 219)',
'rgb(255, 245, 204)',
'rgb(251, 219, 255)',
'rgb(255, 219, 234)',
];
const sourceIconMap = {
mysql: MySQLIcon,
sqlserver: SQLServerIcon,
webapi: WebAPIIcon,
};
export { tagColors, tagBackgroundColors, sourceIconMap };
import style from '../ReportsManage.less';
import extraComponents from '../extra/extraComponents';
import moment from 'moment';
import { Tag } from 'antd';
import { hasMoney, isNumber, returnHandledNumber } from './utils';
import { tagColors, tagBackgroundColors } from './constant';
/**
* @params: config下的数值的configRule结构如下,[{最大值: 10,最小值: 0,颜色:'#AAAAAA'}];
* @business: configRule有值,则按照configRule设置;没有,按照color设置; 有最大值,无最小值;['', 1]
* 有最大值,有最小值;[2,
*
* 10]
* 有最小值,无最大值;[11,'']
*/
// 链接 功能 弹窗功能待提出需求
// 函数名、属性、...
const clickLink = (config) => {
return window.open(config.configItems, '_blank');
};
const handleUrl = (allWidgets, config) => {};
const handleConfigUrl = (config, record) => {
let _configs = config.configItems.split('|');
// type = 替换|跳转;
let _type = '';
//url=project/pandawork/contractDetails/index?ageSize=100&accountName=软件订单台账|contractCode=${订单编号}|company=${分公司}
let _url = '';
let _params = {};
_configs.forEach((item) => {
if (item.includes('type=')) _type = item.replace('type=', '');
if (item.includes('url=')) {
let _tempUrl = item.replace('url=', '');
let _urlArray = _tempUrl.split('?');
if (_urlArray[1]) {
_urlArray[1].split('&').forEach((param) => {
let _paramArr = param.split('=');
if (_paramArr[1] && _paramArr[1].includes('${') && _paramArr[1].includes('}')) {
let _key = _paramArr[1].replace(/\$\{|\}/g, '');
_params[_paramArr[0]] = record[_key];
} else {
_params[_paramArr[0]] = _paramArr[1];
}
});
}
_url = _urlArray[0];
}
});
return { url: _url, type: _type, params: _params };
};
const clickWidget = (config, text, record, showComponents, setDetailsConfig) => {
// 功能跳转接口
// type=替换|url=product/ReportsManage/ReportsSetting?accountName=${ID}&pageSize=100&title=${name}
if (!config.configItems) return message.error('未配置跳转信息');
// setDetailsComponentVisible(true);
showComponents(true);
let urlConfig = handleConfigUrl(config, record);
// setDetailConfig(urlConfig);
setDetailsConfig(urlConfig);
};
const clickModal = (config, showModal, setExtra) => {
let _splitArr = config.configItems.split('&');
let _fn = _splitArr[0] || 'default';
_splitArr.splice(0, 1);
let _data = {};
_splitArr.forEach((item) => {
let _item = item.split('=');
_data[_item[0]] = _item[1];
});
// setExtraModal(true);
showModal(true);
return setExtra(extraComponents[_fn](_data));
};
const returnOpacity = (rgba) => {
if (!rgba) rgba = 'rgba(0,0,0,.65)';
let _str = rgba.replace('rgba(', '').replace(')', '');
let _splitStr = _str.split(',');
return `rgba(${_splitStr[0]},${_splitStr[1]},${_splitStr[2]},.25)`;
};
export const handleNumber = (config, number) => {
let _color = '';
let _number;
if (number) _number = Number(number); // 当设置精度后,会被转成字符串
if (config.type === '数值' && config.numericalConfigs && config.numericalConfigs.length) {
config.numericalConfigs.forEach((item) => {
// 接口对于数值类型的返回为null
if (!_color) {
let _max = isNumber(item.maxValue) ? item.maxValue : '';
let _min = isNumber(item.minValue) ? item.minValue : '';
if (_max !== '' && _min === '') {
_color = _number <= Number(_max) ? '' : item.color;
} else if (_min !== '' && _max === '') {
_color = _number > Number(_min) ? item.color : '';
} else {
_color = _number > Number(_min) && _number <= Number(_max) ? item.color : '';
}
}
});
} else if (config.type === '数值标签' && config.labelConfigs && config.labelConfigs.length) {
console.log('数值标签');
_color = 'red';
} else if (config.color) {
_color = config.color;
}
return number ? (
<span>
<span
className={style.prefixOrSuffix}
style={{
color: _color,
}}
>
{config.prefix || ''}
</span>
<span
style={{
color: _color,
margin: '0 5px',
}}
>
{returnHandledNumber(config.configItems, number)}
</span>
<span className={style.prefixOrSuffix} style={{ color: _color }}>
{config.suffix || ''}
</span>
</span>
) : (
'-'
);
};
export const handleNumberTag = (config, number) => {
let _color = '';
let _map = {};
// 标签需要设置分隔符 2022年7月13日 ChenLong
let _configItems = config.configItems.split('|');
let _configMap = {};
_configItems.forEach((item) => {
let _arr = item.split('=');
_configMap[_arr[0]] = _arr[1];
});
// 处理label的颜色
if (config.labelConfigs && config.labelConfigs.length) {
config.labelConfigs.forEach((item) => {
_map[item.labelValue] = item.color;
});
}
_color = config.color || 'rgba(0,0,0,.85)';
// String(text)为了解决可能存在数值类型的数据需要设置成标签的需求
// return String(text).split(_configMap['分隔符']).map(item => <Tag color={_map[item]}>{item}</Tag>);
// let a = 'abc' a.split(undefined); a = ['abc']
return (
<Tag
style={{
background: mapTag(_map, number) || _color,
border: `1px solid ${mapTag(_map, number) || _color}`,
borderRadius: 2,
color: mapTag(_map, number)
? tagColors[tagBackgroundColors.findIndex((c) => c === mapTag(_map, number))]
: `rgba(0, 0, 0, .65)`,
}}
>
{(config.prefix || '') +
returnHandledNumber(config.configItems, number) +
(config.suffix || '')}
</Tag>
);
};
/** @params: 标签形态的configRule,[{标签值:'字符串',颜色: '#AAAAAA'}]; */
/* 支持正则配置 RegExp */
export const handleTag = (config, text) => {
let _color = '';
let _map = {};
// 标签需要设置分隔符 2022年7月13日 ChenLong
let _configItems = config.configItems.split('|');
let _configMap = {};
_configItems.forEach((item) => {
let _arr = item.split('=');
_configMap[_arr[0]] = _arr[1];
});
// 处理label的颜色
if (config.labelConfigs && config.labelConfigs.length) {
config.labelConfigs.forEach((item) => {
_map[item.labelValue] = item.color;
});
}
_color = config.color || 'rgba(0,0,0,.85)';
// String(text)为了解决可能存在数值类型的数据需要设置成标签的需求
// return String(text).split(_configMap['分隔符']).map(item => <Tag color={_map[item]}>{item}</Tag>);
// let a = 'abc' a.split(undefined); a = ['abc']
return String(text)
.split(_configMap['分隔符'])
.map((item) => (
<Tag
style={{
background: mapTag(_map, item) || _color,
border: `1px solid ${mapTag(_map, item) || _color}`,
borderRadius: 2,
color: mapTag(_map, item)
? tagColors[tagBackgroundColors.findIndex((c) => c === mapTag(_map, item))]
: `rgba(0, 0, 0, .65)`,
}}
>
{item}
</Tag>
));
};
const mapTag = (map, key) => {
if (map[key]) {
return map[key];
} else {
let _keys = Object.keys(map);
return _keys.reduce((final, _key) => {
let isRegExp = _key.includes('RegExp=');
let reg = new RegExp(_key.replace('RegExp=', ''));
if (isRegExp && reg.test(key)) {
final = map[_key];
}
return final;
}, '');
}
};
export const handleText = (config, text) => {
return <span style={{ color: config.color || 'rgba(0,0,0,.85)' }}>{text}</span>;
};
export const handleLink = (config, text) => {
return (
<span
className={style.link}
style={{
color: config.color || 'rgba(0,0,0,.85)',
}}
onClick={() => clickLink(config)}
>
{text}
</span>
);
};
export const handleWidget = (config, text, record, showComponents, setDetailsConfig) => {
return (
<span
style={{ color: config.color }}
className={style.link}
onClick={() => clickWidget(config, text, record, showComponents, setDetailsConfig)}
>
{text}
</span>
);
};
export const handleModal = (config, text, showModal, setExtra) => {
return (
<span
className={style.link}
style={{ color: config.color || 'rgba(0,0,0,.85)' }}
onClick={() => clickModal(config, showModal, setExtra)}
>
{text}
</span>
);
};
// 日期
export const handleDateString = (config, text) => {
return text ? moment(text).format('YYYY-MM-DD') : '-';
};
// 时刻
export const handleDateTimeString = (config, text) => {
return text ? moment(text).format('YYYY-MM-DD HH:mm:ss') : '-';
};
// 处理pageSize
export const handlePageSize = (numStr) => {
return numStr && isNumber(Number(numStr)) ? Number(numStr) : false;
};
// 处理默认排序
export const handleSortFields = (sortFields) => {
return (sortFields && sortFields.split(',')) || [];
};
const isObject = (obj) => {
return Object.prototype.toString.call(obj) === '[object Object]';
};
const isString = (obj) => {
return Object.prototype.toString.call(obj) === '[object String]';
};
const isNumber = (num) => {
return Object.prototype.toString.call(num) === '[object Number]';
};
const isArray = (arr) => {
return Object.prototype.toString.call(arr) === '[object Array]';
};
const hasMoney = (configItems) => {
if (!configItems) return false;
let _items = configItems.split('|');
return !!_items.find((item) => item === '金额');
};
const isSelect = (configItems) => {
if (!configItems) return false;
let _items = configItems.split('|');
return !!_items.find((item) => item === 'renderAsSelect');
};
// options=name1[.value1],name2[.value2],name3[.value3];
const returnOptions = (configItems) => {
if (!configItems) return false;
let _items = configItems.split('|');
let _options = _items.find((item) => item.includes('options='));
if (!_options) return false;
return _options.replace('options=', '').split(',');
};
const returnRows = (configItems) => {
if (!configItems) return 3;
let _items = configItems.split('|');
let _options = _items.find((item) => item.includes('rows='));
if (!_options) return 3;
let _rows = Number(_options.replace('rows=', ''));
return !isNaN(_rows) && _rows >= 1 ? _rows : 3;
};
const returnCols = (configItems) => {
if (!configItems) return 1;
let _items = configItems.split('|');
let _options = _items.find((item) => item.includes('cols='));
if (!_options) return 1;
let _cols = Number(_options.replace('cols=', ''));
return !isNaN(_cols) && _cols <= 3 && _cols >= 0 ? _cols : 1;
};
/**
* @description: 用来在summary中处理数值的配置
* @params: 参数描述
* @date: 2022/8/10
* @author: ChenLong
*/
const returnHandledNumber = (configItems, num, isSummary) => {
// 精度、前缀、后缀、倍率
// $_d|_d%|_d*0.0001|金额|0.00
if (isNaN(num)) return '-';
if (!configItems) return num;
num = Number(num);
let _items = configItems.split('|');
/* let prefix = '';
let suffix = '';*/
let template = '_d';
let precision = 0;
let rate = 1;
_items.forEach((item) => {
let _arr = [];
if (item.match(/_d[^\*]/)) {
// 后缀
template = item;
} else if (item.match(/^_d\*/)) {
// 倍率
let _rate = item.replace(/_d\*/, '');
rate = _rate && isSummary ? Number(_rate) : 1; // 总结栏计算需要计算倍率,其他不用
} else if (item.match(/^0\./)) {
// 精度
precision = item.replace('0.', '').length;
}
});
// 可能存在NaN的问题
let final = _items.includes('金额')
? Number((num * rate).toFixed(precision)).toLocaleString()
: Number((num * rate).toFixed(precision)).toLocaleString();
return template.replace(/_d/, isString(final) ? final : '-');
};
/**
* @description: 返回configItems内配置的默认值、默认模式等等
* @params: 参数描述
* @date: 2022/8/12
* @author: ChenLong
* @params:
* configItems 报表字段的配置 例如 defaultValue=智慧水务
*
* defaultDateModel=customer|defaultDateValue=2022-01-01,2022-12-31;
* keysArray
*
* 所需要返回的值的key的集合,比如你需要获取configItems中的’defaultValue‘,那么keysArray=['defaultValue'];
* @returns:
* defaultValue 通用参数 默认值
* defaultDateModel 时间参数 默认模式
* defaultDateValue 时间参数 默认时间
*/
const returnDefaultValueOrConfigs = (configItems = '', keysArray = []) => {
let _map = {};
let _configItemsArray = configItems.split('|');
keysArray.forEach((key) => {
_map[key] = _configItemsArray.find((item) => item.includes(`${key}=`))?.replace(`${key}=`, '');
});
return _map;
};
function downloadFunc(url, name, target = '_self') {
const a = document.createElement('a');
a.href = url;
a.target = target;
a.download = name;
a.click();
a.remove();
}
/**
* @description: 校验文件的名称是否包含特殊字符
* @params: {Object: File} file file对象 { special:Boolean } 是否去除/的匹配
* @date: 2021/12/8
* @author: ChenLong
* @returns {Object} {type: error | success ,content: 提示...}
*/
function filenameVerification(file, special) {
// 文件名含有特殊字符 提示不能上传 {+,:/?#[]@!$&\\*+;=}
// 规则对象(flag)
var flag = !special
? new RegExp("[`~!@#$^&*=|{}':;',\\[\\]/?~!@#¥&*——|{}【】‘;:”“'。,、?]")
: new RegExp("[`~!@#$^&*=|{}':;',[\\]?~!@#¥&*——|{}【】‘;:”“'。,、?]");
if (flag.test(file.name)) {
return {
type: 'error',
content: `文件名格式错误,请检查文件名是否含有特殊字符${"~!@#$^&*=|{}':;',\\[\\]/?~!@#¥&*——|{}【】‘;:”“'。,、?"}`,
};
}
return {
type: 'success',
content: `上传成功!`,
};
}
export {
isObject,
isString,
isNumber,
hasMoney,
isArray,
returnHandledNumber,
returnDefaultValueOrConfigs,
downloadFunc,
filenameVerification,
isSelect,
returnOptions,
returnRows,
returnCols,
};
export const SERVICE_APP_GET_UI_META = 'app.getUIMeta';
export const SERVICE_APP_LOGIN_MODE = {
password: 'password',
dingding: 'dingding',
weixin: 'weixin',
phone: 'phone',
};
export const LOGIN_DISPLAY = {
Account: 'Account',
WeChart: 'WeChart',
Mobile: 'Mobile',
};
export const LOGIN_WAY = {
Account: 'pdw',
WeChart: 'iotWechat',
Mobile: 'iotPhone',
};
export const WX_REDIRECT_URI = 'https://panda-water.com/civbase/user/login';
export const SERVICE_INTERFACE_SUCCESS_CODE = 0;
export const SERVICE_INTERFACE_PARAMS_EXCEPTION_CODE = -1; // 服务参数异常
export const SERVICE_INTERFACE_HANDLE_EXCEPTION_CODE = -2; // 服务处理异常
export const SERVICE_APP_CLOSE_ALL_TABS = 'app.close.tabs';
export const REQUEST_HTTP = 'http';
export const REQUEST_POP = 'pop';
export const REQUEST_METHOD_GET = 'get';
export const REQUEST_METHOD_POST = 'post';
export const REQUEST_METHOD_PUT = 'put';
export const REQUEST_METHOD_DELETE = 'delete';
export const RESPONSE_TYPE = 'blob';
import { Modal, notification } from 'antd';
import { instanceRequest, service } from '@wisdom-utils/utils';
import ReportService from './service/report';
const { warning } = Modal;
// eslint-disable-next-line no-return-await
instanceRequest.reportCodeError = true;
const codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误), 或当前的会话已超时,请重新登录',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
let instance = null;
instanceRequest.setErrorHandler((error) => {
const { response } = error;
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, config } = response;
if (status === 401) {
if (!instance) {
instance = warning({
title: '错误信息',
content: `${codeMessage[status]}`,
centered: true,
onOk(close) {
window.share && window.share.event && window.share.event.emit('triggerLoginout');
close();
},
});
}
} else {
notification.error({
message: `请求错误 ${status}: ${config.url}`,
description: errorText,
});
}
} else if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
}
return response;
});
const reportService = service(ReportService);
export { reportService };
/*
** 轻量化报表平台接口
** create by ChenLong on 2022/6/24
** 功能路径:src\api\service\report.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/
import { request } from '@wisdom-utils/utils';
import * as constants from '../constants';
const BASEURL = '/PandaAssets/Assets/ReportManager';
export const API = {
GET_REPORT_INFO: `${BASEURL}/GetReportInfo`, // 获取报表信息
GET_REPORT_FILTER_VALUE: `${BASEURL}/GetReportFilterValue`, // 获取过滤字段的值的枚举
GET_REPORT_FILTER_VALUES: `${BASEURL}/GetReportFilterValues`, // 获取过滤字段的值的枚举
GET_REPORT_CONFIG_LIST: `${BASEURL}/GetReportConfigList`, // 获取配置列表
GET_REPORT_DETAILS_INFO: `${BASEURL}/GetReportDetailsInfo`, // 获取配置详情
GET_TABLES: `${BASEURL}/GetTables`, // 查询表
GET_TABLE_FIELDS: `${BASEURL}/GetTableFields`, // 查询表内的字段
ADD_REPORT_INFO: `${BASEURL}/AddReportInfo`, // 创建报表主表、关联报表子表
EDIT_REPORT_INFO: `${BASEURL}/AddReportInfo`,
ADD_REPORT_DETAIL_INFO: `${BASEURL}/AddReportDetailInfo`, // 附加子表字段到主表
DELETE_REPORT_INFO: `${BASEURL}/DeleteReportInfo`, // 删除报表
DELETE_REPORT_DETAIL_INFO: `${BASEURL}/DeleteReportDetailInfo`, // 删除字段
EXPORT_ACCOUNT_DATA: `${BASEURL}/ExportAccountData`, // 导出数据
SAVE_REPORT_LIST_SORT_FIELDS: `${BASEURL}/SaveReportListSortFields`, // 保存排序
ADD_REPORT_DETAIL_INFO_INDEX: `${BASEURL}/AddReportDetailInfoIndex`, // 变更接口顺序
UPDATE_REPORT_DATA: `${BASEURL}/UpdateReportData`, // 更新报表数据
GET_REPORT_DETAILS: `${BASEURL}/GetReportDetails`, // 获取报表配置
DEL_REPORT_DATA: `${BASEURL}/DelReportData`, // 删除报表数据
SET_REPORT_ALLOW: `${BASEURL}/SetReportAllow`, // 设置关注
ADD_REPORT_DATA: `${BASEURL}/AddReportData`, // 添加报表数据
EXPORT_JPG: `${BASEURL}/ExportJPGAccountData`,
EXPORT_REPORT_CONFIG: `${BASEURL}/ExportReportConfig`,
IMPORT_REPORT_CONFIG: `${BASEURL}/ImportReportConfig`,
// 多数据源
GET_DATA_SOURCES: `${BASEURL}/GetDataSources`, // 获取数据源列表
ADD_DB_CONNECTION: `${BASEURL}/AddDbConnection`, // 新增/编辑数据源
DELETE_DB_CONNECTION: `${BASEURL}/DeleteDbConnection`, // 删除数据源
GET_DB_SOURCES: `${BASEURL}/GetDBSources`, // 获取数据库
TEST_CONNECTION: `${BASEURL}/TestConnection`, // 测试链接
DEL_REPORT_CHILD: `${BASEURL}/DelReportChlid`, // 删除挂接关系
};
const reportService = {
getReportInfo: {
url: API.GET_REPORT_INFO,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
getReportFilterValue: {
url: API.GET_REPORT_FILTER_VALUE,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
getReportFilterValues: {
url: API.GET_REPORT_FILTER_VALUES,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
getReportConfigList: {
url: API.GET_REPORT_CONFIG_LIST,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
getReportDetailsInfo: {
url: API.GET_REPORT_DETAILS_INFO,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
getTables: {
url: API.GET_TABLES,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
getTableFields: {
url: API.GET_TABLE_FIELDS,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
addReportInfo: {
url: API.ADD_REPORT_INFO,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
editReportInfo: {
url: API.EDIT_REPORT_INFO,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
addReportDetailInfo: {
url: API.ADD_REPORT_DETAIL_INFO,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
deleteReportInfo: {
url: API.DELETE_REPORT_INFO,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
deleteReportDetailInfo: {
url: API.DELETE_REPORT_DETAIL_INFO,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
saveReportListSortFields: {
url: API.SAVE_REPORT_LIST_SORT_FIELDS,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
addReportDetailInfoIndex: {
url: API.ADD_REPORT_DETAIL_INFO_INDEX,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
updateReportData: {
url: API.UPDATE_REPORT_DATA,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
getReportDetails: {
url: API.GET_REPORT_DETAILS,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
delReportData: {
url: API.DEL_REPORT_DATA,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
setReportAllow: {
url: API.SET_REPORT_ALLOW,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
addReportData: {
url: API.ADD_REPORT_DATA,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
exportJPG: {
url: API.EXPORT_JPG,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
exportConfig: {
url: API.EXPORT_REPORT_CONFIG,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
importConfig: {
url: API.IMPORT_REPORT_CONFIG,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
getDataSources: {
url: API.GET_DATA_SOURCES,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
addDbConnection: {
url: API.ADD_DB_CONNECTION,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
deleteDbConnection: {
url: API.DELETE_DB_CONNECTION,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
getDbSources: {
url: API.GET_DB_SOURCES,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
testConnection: {
url: API.TEST_CONNECTION,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_METHOD_POST,
},
delReportChild: {
url: API.DEL_REPORT_CHILD,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_METHOD_GET,
},
};
export const submitReportData = (params, data) =>
request({
url: API.UPDATE_REPORT_DATA,
method: 'post',
params,
data,
});
export const exportAccountData = (options, params, data) =>
request({
url: API.EXPORT_ACCOUNT_DATA,
method: 'post',
...options,
params,
data,
});
export const exportJPG = (options, data) => {
return request({
url: API.EXPORT_JPG,
method: 'post',
...options,
data,
});
};
export const addReportDetailInfoIndex = (data) =>
request({
url: API.ADD_REPORT_DETAIL_INFO_INDEX,
method: 'post',
data,
});
export const importReportConfig = (options, params, data) =>
request({
url: API.IMPORT_REPORT_CONFIG,
method: 'post',
...options,
params,
data,
});
export const exportReportConfig = (options, params) =>
request({
url: API.EXPORT_REPORT_CONFIG,
method: 'get',
...options,
params,
});
export default reportService;
const AccountBaseURL = '/PandaWorkFlow/WorkFlow/AccountManage';
export const uploadFileUrl = `${AccountBaseURL}/UploaderFiles`; // 上传文件链接
export const downloadFileUrl = `${AccountBaseURL}/DownloadFiles`; // 下载/播放文件链接
/**
* 时间组选择:支持 全部,日,月,年,自定义 类型 props:
* onChange: ({dateFrom, dateTo}, model) => {}。切换时间类型或时间会触发onChange,并传递选择的时间范围和类型。
* 注:dateFrom和dateTo都是格式化后的字符串
* format: 格式化字符串格式,默认"YYYY-MM-DD HH:mm:ss",参看moment格式化支持的
*/
import React, { useState, useEffect } from 'react';
import { Radio, Space, DatePicker } from 'antd';
import moment from 'moment';
const dateForModel = (model, date = moment()) => {
if (!date) {
result = { dateFrom: null, dateTo: null };
return result;
}
let result = { dateFrom: null, dateTo: null };
switch (model) {
case 'day':
result = { dateFrom: date.clone().startOf('day'), dateTo: date.clone().endOf('day') };
break;
case 'week':
result = { dateFrom: date.clone().startOf('week'), dateTo: date.clone().endOf('week') };
break;
case 'month':
result = { dateFrom: date.clone().startOf('month'), dateTo: date.clone().endOf('month') };
break;
case 'quarter':
result = { dateFrom: date.clone().startOf('quarter'), dateTo: date.clone().endOf('quarter') };
break;
case 'year':
result = { dateFrom: date.clone().startOf('year'), dateTo: date.clone().endOf('year') };
break;
case 'all':
default:
result = { dateFrom: null, dateTo: null };
break;
}
return result;
};
const textForModel = (model) => {
switch (model) {
case 'day':
return '日';
case 'week':
return '周';
case 'month':
return '月';
case 'quarter':
return '季度';
case 'year':
return '年';
case 'all':
return '全部';
case 'custom':
return '自定义';
default:
return model;
}
};
const useDataGroup = (defaultValue = { dateFrom: null, dateTo: null }, defaultModel = 'all') => {
const [model, setModel] = useState(defaultModel);
const [value, setValue] = useState(defaultValue);
const updateValeu = (_value, _model) => {
setModel(_model);
setValue(_value);
};
return [value, model, updateValeu];
};
const defaultFormat = 'YYYY-MM-DD HH:mm:ss';
const defaultShowModels = ['all', 'week', 'month', 'quarter', 'year', 'custom'];
const DatePickerGroup = ({
onChange,
format = defaultFormat,
showModels = defaultShowModels,
defaultModel = 'all',
defaultDate,
value,
dateModel,
}) => {
const [model, setModel] = useState(defaultModel);
const [dateValue, setDateValue] = useState(() => dateForModel(defaultModel, defaultDate));
useEffect(() => {
if (value || dateModel) {
setModel(dateModel);
setDateValue(value);
}
}, [value, dateModel]);
// 切换类型
const changeModel = (e) => {
const _model = e.target.value;
const _dateValue = dateForModel(_model);
if (!value && !dateModel) {
setModel(_model);
setDateValue(_dateValue);
if (_model === 'custom') return;
}
const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : '';
const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : '';
onChange &&
onChange(
{
dateFrom: _dateFrom,
dateTo: _dateTo,
},
_model,
);
};
// 切换时间
const changeDate = (date, dateString) => {
const _dateValue = dateForModel(model, date);
const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : '';
const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : '';
if (!value && !dateModel) {
setDateValue(_dateValue);
}
onChange &&
onChange(
{
dateFrom: _dateFrom,
dateTo: _dateTo,
},
model,
);
};
// 切换范围时间
const changeRangeDate = (dates, dateStrings) => {
const _dateValue = { dateFrom: dates?.[0], dateTo: dates?.[1] };
const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : '';
const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : '';
if (!value && !dateModel) {
setDateValue(_dateValue);
}
onChange &&
onChange(
{
dateFrom: _dateFrom,
dateTo: _dateTo,
},
model,
);
};
// 渲染时间选择器
const renderDatePicker = () => {
let _result = null;
switch (model) {
case 'day':
_result = <DatePicker onChange={changeDate} value={dateValue.dateFrom} />;
break;
case 'week':
_result = <DatePicker picker="week" onChange={changeDate} value={dateValue.dateFrom} />;
break;
case 'month':
_result = <DatePicker picker="month" onChange={changeDate} value={dateValue.dateFrom} />;
break;
case 'quarter':
_result = <DatePicker picker="quarter" onChange={changeDate} value={dateValue.dateFrom} />;
break;
case 'year':
_result = <DatePicker picker="year" onChange={changeDate} value={dateValue.dateFrom} />;
break;
case 'custom':
_result = (
<DatePicker.RangePicker
onChange={changeRangeDate}
value={[dateValue.dateFrom, dateValue.dateTo]}
/>
);
break;
case 'all':
default:
_result = null;
break;
}
return _result;
};
return (
<Space size={8}>
<Radio.Group value={model} onChange={changeModel} style={{ whiteSpace: 'nowrap' }}>
{showModels.map((item) => (
<Radio.Button value={item} key={item}>
{textForModel(item)}
</Radio.Button>
))}
</Radio.Group>
{renderDatePicker()}
</Space>
);
};
export { useDataGroup };
export default DatePickerGroup;
import React from 'react';
import BasicReport from '../index';
const Demo = () => {
return (
<div>
<h3>报表</h3>
<div style={{ height: '600px' }}>
<BasicReport
params={{
reportName: '订单合同',
}}
/>
</div>
</div>
);
};
export default Demo;
import React from 'react';
import ReportsManage from './ReportsManage/ReportsManage';
const BasicReport = (props) => {
return <ReportsManage {...props} />;
};
export default BasicReport;
......@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.11](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/datepickercustom@1.1.10...@wisdom-components/datepickercustom@1.1.11) (2023-02-01)
### Bug Fixes
- 修改日期选择样式 ([c52e623](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/c52e623c2e276449feb395185c8c6bb52ca96527))
- 组态修改 ([7acd320](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7acd32085d894c30579fd9caf3ec75af93e217e3))
## [1.1.10](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/datepickercustom@1.1.9...@wisdom-components/datepickercustom@1.1.10) (2022-11-30)
### Bug Fixes
......
{
"name": "@wisdom-components/datepickercustom",
"version": "1.1.10",
"version": "1.1.11",
"description": "> TODO: description",
"author": "lijiwen <961370825@qq.com>",
"homepage": "",
......
......@@ -5,20 +5,19 @@
width: 230px;
}
.@{datepicker-custom-prefix-cls}-quarter {
// :global {
.ant-picker-year-panel,
.ant-picker-quarter-panel {
.@{ant-prefix}-picker-year-panel,
.@{ant-prefix}-picker-quarter-panel {
width: 230px;
}
// 修改选中的年份、季度背景颜⾊
.ant-picker-cell-selected {
.ant-picker-cell-inner {
.@{ant-prefix}-picker-cell-selected {
.@{ant-prefix}-picker-cell-inner {
background: #1890ff;
}
}
// 使⽤CSS改变季度选择器的内容
.ant-picker-quarter-panel {
.ant-picker-content {
.@{ant-prefix}-picker-quarter-panel {
.@{ant-prefix}-picker-content {
// 使季度选择器可以换⾏成两排
tr {
display: flex;
......@@ -35,14 +34,14 @@
}
}
// 使before伪元素和按钮背景颜⾊⼀致
.ant-picker-cell-selected {
.@{ant-prefix}-picker-cell-selected {
&::before {
color: #fff;
background: #1890ff;
}
}
// 控制伪元素所占宽度
.ant-picker-cell {
.@{ant-prefix}-picker-cell {
&::before {
right: auto;
left: auto;
......@@ -53,30 +52,29 @@
}
}
// 隐藏季度选择器的按钮,⽤伪元素代替
.ant-picker-cell-inner {
.@{ant-prefix}-picker-cell-inner {
display: none;
}
// 根据title更换相应伪元素的content,使其代替原本的按钮
.ant-picker-cell[title$='-Q1'] {
.@{ant-prefix}-picker-cell[title$='-Q1'] {
&::before {
content: '第一季度';
}
}
.ant-picker-cell[title$='-Q2'] {
.@{ant-prefix}-picker-cell[title$='-Q2'] {
&::before {
content: '第二季度';
}
}
.ant-picker-cell[title$='-Q3'] {
.@{ant-prefix}-picker-cell[title$='-Q3'] {
&::before {
content: '第三季度';
}
}
.ant-picker-cell[title$='-Q4'] {
.@{ant-prefix}-picker-cell[title$='-Q4'] {
&::before {
content: '第四季度';
}
}
}
// }
}
......@@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.5](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/loadbox@1.1.4...@wisdom-components/loadbox@1.1.5) (2023-01-05)
**Note:** Version bump only for package @wisdom-components/loadbox
## [1.1.4](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/loadbox@1.1.3...@wisdom-components/loadbox@1.1.4) (2022-05-05)
### Bug Fixes
......
{
"name": "@wisdom-components/loadbox",
"version": "1.1.4",
"version": "1.1.5",
"description": "> TODO: description",
"author": "lijiwen <961370825@qq.com>",
"homepage": "",
......
......@@ -28,7 +28,7 @@ const Demo = (props) => {
justifyContent: 'center',
}}
>
<LoadBox spinning={spinning} />
<LoadBox spinning={spinning} tip={'加载'} />
</div>
<div style={{ marginTop: '20px' }}>
<Button onClick={startClick} style={{ marginRight: '20px' }}>
......
......@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.2.21](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/richtext@0.2.20...@wisdom-components/richtext@0.2.21) (2023-01-11)
### Bug Fixes
- 富文本编辑器文档完善 ([2772dbe](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/2772dbe226b9bce2b904d2a4455b09d09c65712e))
- 富文本维护 ([c7a930b](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/c7a930b832e7681241a8680e260fb80a7ee1d48f))
## [0.2.20](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/richtext@0.2.6...@wisdom-components/richtext@0.2.20) (2022-12-19)
### Bug Fixes
......
{
"name": "@wisdom-components/richtext",
"version": "0.2.20",
"version": "0.2.21",
"description": "> TODO: description",
"author": "hongmye <1014185119@qq.com>",
"homepage": "",
......
......@@ -15,10 +15,32 @@ group:
<code src="./demos/demo.jsx">
### 合计
### 参数
<!-- <code src="./demos/Summary.tsx"> -->
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| projectId | 项目 ID(通过项目 ID 获取项目人员,可在输入@符号时显示 ) | Number,String | null |
| personList | personList 传任务相关人员列表(如 创建、负责、跟进人),同时传入 projectId,personList,下拉列表默认显示为任务相关人员,加项目人员(做了去重,任务相关人员在最上面) | Array | [] |
| config | 框架 wangEditor 的配置参数 | Object | {} |
| content | 初始内容(内容如果不是初始有的,可调用 setHtml 设置内容) | String | '' |
| fileList | 附件列表 [{name:'xxx.jpg',type:'image/jpg',size:8192,path:'xxxx'}], name 和 path 是必传的,type 为图片可以预览,其它类型文件直接下载 | Array | [] |
## API
## 事件
| 名称 | 描述 |
| ------------ | -------------------------------------------------- |
| onChange | 内容改变回调 |
| onChangeFile | 文件改变回调(没有,则工具栏上不显示上传附件按钮) |
## ref事件
| 名称 | 描述 |
| ------------ | -------------------------------------------------- |
| setHtml | 设置内容 |
| onClear | 清除内容 |
| getHtml | 获取html字符串 |
| getText | 获取纯内容(不包含标签) |
## API
api 参考 Antd Table 组件 https://www.wangeditor.com/v4/
/*
* @Title:
* @Author: hongmye
* @Date: 2022-06-23 16:03:16
*/
// @ts-ignore
import Empty from '@wisdom-components/empty';
import { useEffect, useState } from 'react';
// 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}`,
};
});
column.unshift({
title: '时间',
dataIndex: 'time',
key: 'time',
});
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);
});
};
// @ts-ignore
return (
<div style={{ height: '800px' }}>
{/* {!!dataSource.length && (
<BasicTable
dataSource={dataSource}
columns={columns}
bordered={false}
pagination={{ pageSize: 20, size: 'default' }}
/>
)} */}
{!dataSource.length && <Empty description={'暂无数据'} />}
</div>
);
};
export default Demo;
const baseUrl = 'https://www.fastmock.site/mock/162c15dca15c4dba9ba51e0a0b76929b/api';
/**
* 1.引入组件 import RichText from '@wisdom-components/RichText';
* 示例:<RichText
content={this.state.content}
personList={this.state.personList}
placeholder={'placeholder属性值'}
onChange={val => {
this.setState({ content: val });
}}
onChangeFile={arr => {
this.setState({ fileList: arr });
}}
fileList={this.state.fileList}
projectId={19}
ref={this.myRichText}
/>
*
* 2.传递方法 onChange 每次更改内容回调
*
* 3.传值接收 可选值 projectId 项目id,根据项目id获取项目参与人员,
* 可选值 personList 人员列表 示例:[{userId:1,userName:'xxx'}]
* 可选值 config 框架wangEditor的配置参数
*
* 4.注意事项 projectId和personList只用传一个,projectId优先级高于personList
* content内容如果不是初始有的,可调用setHtml设置内容
*
* 2022-03-21新增图片预览,附件上传功能
* 新增方法:onChangeFile 每次附件更改回调 若不传则不显示附件上传按钮
* fileList 附件列表 示例:[{name:'xxx.jpg',type:'image/jpg',size:8192,path:'xxxx'}]
* 其中name和path是必传的,type为图片可以预览,其它类型文件直接下载
*
* 2022-04-29 修改@人员列表逻辑
* personList 传任务相关人员列表(如 创建、负责、跟进人),同时传入projectId,personList
* 下拉列表默认显示为任务相关人员,加项目人员(做了去重,任务相关人员在最上面)
* @搜索时,搜索全部人员
*/
import { Image, message, Spin } from 'antd';
import classNames from 'classnames';
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
......@@ -188,7 +226,6 @@ const RichText = forwardRef((props, ref) => {
return;
}
range.setEnd(selection.getRangeAt(0).commonAncestorContainer, selection.focusOffset);
// console.log('🚀 ~ range', range.toString(), tempList, selectList);
const str = range.toString() || '';
moveListBox();
handleChange(str, tempList);
......@@ -239,7 +276,6 @@ const RichText = forwardRef((props, ref) => {
}
if (evet.key === 'Enter') {
// 解决无法回车换行的bug
console.log(selectBoxRef.current.style.display === 'block');
if (selectBoxRef.current.style.display === 'block') {
evet.preventDefault();
if (selectPerson[selectPersonIndex]) {
......@@ -346,7 +382,6 @@ const RichText = forwardRef((props, ref) => {
}
};
const handleChange = (val, list) => {
console.log('🚀 ~ val', val);
if (timer) {
clearTimeout(timer);
}
......
......@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.5.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/timerangepicker@1.4.8...@wisdom-components/timerangepicker@1.5.0) (2023-01-12)
### Features
- 时间选择器增加默认 visible 属性 ([6f5ee7a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/6f5ee7ad177723321e894e2136e104b593aa99a9))
## [1.4.8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/timerangepicker@1.4.7...@wisdom-components/timerangepicker@1.4.8) (2022-06-02)
### Bug Fixes
......
{
"name": "@wisdom-components/timerangepicker",
"version": "1.4.8",
"version": "1.5.0",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
......
......@@ -16,8 +16,9 @@ const TimeRangePicker = ({
dataSource,
timeProps,
onChange,
defaultVisible
}) => {
const [visible, setVisible] = useState(false);
const [visible, setVisible] = useState(defaultVisible);
const [visibleKey, setVisibleKey] = useState(null);
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
......@@ -104,6 +105,7 @@ TimeRangePicker.defaultProps = {
dataSource: [],
timeProps: {},
onChange: function (v) {},
defaultVisible:false
};
TimeRangePicker.propTypes = {
......@@ -114,6 +116,7 @@ TimeRangePicker.propTypes = {
dataSource: PropTypes.array,
timeProps: PropTypes.object,
onChange: PropTypes.func,
defaultVisible: PropTypes.bool
};
export default TimeRangePicker;
......
......@@ -2,6 +2,50 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.15](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.14...@wisdom-components/ec_configurationview@1.4.15) (2023-01-31)
### Bug Fixes
- 修改获取画板参数 ([e3245e2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e3245e2ac196ef2a8d2ec416ea53bbe0b72a3d3c))
## [1.4.14](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.12...@wisdom-components/ec_configurationview@1.4.14) (2023-01-12)
### Bug Fixes
- 修改 ([a4b96b3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/a4b96b3061e5116ae3ae0c0647a4e049f6145315))
## [1.4.12](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.11...@wisdom-components/ec_configurationview@1.4.12) (2023-01-12)
**Note:** Version bump only for package @wisdom-components/ec_configurationview
## [1.4.11](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.10...@wisdom-components/ec_configurationview@1.4.11) (2023-01-12)
### Bug Fixes
- 修改 ([da200cb](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/da200cbb9f264fefe3a0a9e98830e604a9446778))
## [1.4.10](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.9...@wisdom-components/ec_configurationview@1.4.10) (2023-01-12)
**Note:** Version bump only for package @wisdom-components/ec_configurationview
## [1.4.9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.8...@wisdom-components/ec_configurationview@1.4.9) (2023-01-09)
### Bug Fixes
- 修改组态 ([e57c508](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e57c5082b91330314f70625873ad68439dea126c))
## [1.4.8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.7...@wisdom-components/ec_configurationview@1.4.8) (2023-01-05)
**Note:** Version bump only for package @wisdom-components/ec_configurationview
## [1.4.7](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.6...@wisdom-components/ec_configurationview@1.4.7) (2023-01-05)
**Note:** Version bump only for package @wisdom-components/ec_configurationview
## [1.4.6](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.5...@wisdom-components/ec_configurationview@1.4.6) (2023-01-05)
**Note:** Version bump only for package @wisdom-components/ec_configurationview
## [1.4.5](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_configurationview@1.4.4...@wisdom-components/ec_configurationview@1.4.5) (2022-12-08)
### Bug Fixes
......
{
"name": "@wisdom-components/ec_configurationview",
"version": "1.4.5",
"version": "1.4.15",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
......@@ -33,9 +33,9 @@
},
"dependencies": {
"@babel/runtime": "^7.17.9",
"@wisdom-components/ec_historyinfo": "1.2.23",
"@wisdom-components/ec_historyview": "1.4.5",
"@wisdom-components/empty": "1.3.9",
"@wisdom-components/loadbox": "1.1.4",
"@wisdom-components/loadbox": "1.1.5",
"@wisdom-components/mqttview": "1.3.6",
"cross-env": "^7.0.3"
}
......
......@@ -23,12 +23,11 @@ group:
## API
| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | -------------------------------- | ------- | ------ |
| name `必需` | 画板名称 | string | '' |
| devices `必需` | 画板设备 | array | [] |
| deviceName | 画板设备名称 | array | [] |
| dictionaryParams | 图标颜色数据字典参数 | object | {} |
| config | 全局 globalConfig,没有时需要传递 | object | {} |
| isZoom | 是否可缩放(手持上建议设置 true) | boolean | false |
| flowShow | 是否水流效果(无数据表现) | boolean | true |
| 参数 | 说明 | 类型 | 默认值 |
| -------------- | -------------------------------- | ------- | ------ |
| name `必需` | 画板名称 | string | '' |
| devices `必需` | 画板设备 | array | [] |
| deviceName | 画板设备名称 | array | [] |
| config | 全局 globalConfig,没有时需要传递 | object | {} |
| isZoom | 是否可缩放(手持上建议设置 true) | boolean | false |
| flowShow | 是否水流效果(无数据表现) | boolean | true |
......@@ -32,15 +32,6 @@ export function getPointAddress(params) {
});
}
// 获取历史数据
export function getHistoryInfo(params) {
return request({
url: `${baseURI}/PandaCore/GCK/Device/SensorsDataForStation`,
method: REQUEST_METHOD_POST,
data: params,
});
}
// 获取数据字典
export function getDictionaryList(params) {
return request({
......
......@@ -15,7 +15,7 @@ import {
} from '@ant-design/icons';
import MqttView from '@wisdom-components/mqttview';
import PropTypes from 'prop-types';
import HistoryInfo from '@wisdom-components/ec_historyinfo';
import HistoryView from '@wisdom-components/ec_historyview';
import * as go from './js/go';
import GuidedDraggingTool from './js/GuidedDraggingTool';
import TopRotatingTool from './js/RotatingTool';
......@@ -23,14 +23,7 @@ import BarLink from './js/BarLink';
import WaterFlowControlView from './js/WaterFlowControlView';
import ConfigurationDetail from './js/ConfigurationDetail';
import DragModal from './js/DragModal';
import {
getSketchPadList,
getSketchPadContent,
getPointAddress,
getHistoryInfo,
getDictionaryList,
getDeviceRealInfo,
} from './apis';
import { getSketchPadList, getSketchPadContent, getPointAddress, getDeviceRealInfo } from './apis';
import {
isNumber,
createGuid,
......@@ -51,9 +44,9 @@ let auModalConfirmFn = null; // 登录模态框的确定事件
let jumpModalProps = null;
let modalProps = {};
let modalWidth = 520;
let historyInfoParams = {};
let historyInfoParams = [];
let nodeData = null; // 选中节点的数据
let twoID = ``;
let twoID = '';
const waterFlow = new WaterFlowControlView();
......@@ -109,14 +102,7 @@ const ConfigurationView = (props) => {
const AuthorFrom = useRef();
const ConfigurationRef = useRef();
const customBack = props.customBack ? props.customBack : () => {};
const {
devices = [],
dictionaryParams,
config,
isZoom = false,
flowShow = true,
deviceName = [],
} = props;
const { devices = [], config, isZoom = false, flowShow = true, deviceName = [] } = props;
const globalConfig = window.globalConfig || config;
let isClose = false;
......@@ -717,7 +703,7 @@ const ConfigurationView = (props) => {
const response = await getSketchPadContent({
dimension: list.dimension,
siteCode: list.siteCode,
fileName: `${list.name}.json`,
fileName: list.deployURL.split('\\').pop(),
_site: globalConfig.userInfo && globalConfig.userInfo.site ? globalConfig.userInfo.site : '',
});
if (response.code === 0) {
......@@ -774,11 +760,20 @@ const ConfigurationView = (props) => {
accountFieldParams,
};
const results = await getDeviceRealInfo(params);
const realDate = results && results.data && results.data.list ? results.data.list : [];
chartDataRender(realDate);
const realData = results && results.data && results.data.list ? results.data.list : [];
chartDataRender(flatten(realData));
} catch (err) {}
};
// 实时数据父子级平铺
const flatten = (arr) => {
return [].concat(
...arr.map((item) =>
item.child ? [].concat(item, ...flatten(item.child)) : [].concat(item),
),
);
};
/** ************************************图表数据处理******************************* */
const chartDataRender = (mqttData) => {
const json = JSON.parse(myDiagram.model.toJson());
......@@ -884,21 +879,13 @@ const ConfigurationView = (props) => {
/** **************************************历史模态渲染****************************************** */
const historyModalRender = (data, list) => {
historyInfoParams = {
stream: [
{
stationCode: list.code,
sensors: data.shName,
pointVersions: list.type,
dateFrom: '',
dateTo: '',
},
],
ignoreOutliers: false, // 过滤异常值
isVertical: false, // 是否展示竖表
zoom: '', // 数据抽稀
unit: '', // 数据抽稀 min h
};
historyInfoParams = [
{
deviceCode: list.code,
sensors: data.shName,
deviceType: list.type,
},
];
setIsHIModalVisible(true);
};
......@@ -2123,19 +2110,19 @@ const ConfigurationView = (props) => {
);
/** **************************************合管连接方式****************************************** */
myDiagram.linkTemplateMap.add(
'linkToLink',
goJS(
'Link',
{ relinkableFrom: true, relinkableTo: true },
goJS('Shape', {
stroke: '#2D9945',
strokeWidth: 2,
}),
),
);
// myDiagram.linkTemplateMap.add(
// 'linkToLink',
// goJS(
// 'Link',
// { relinkableFrom: true, relinkableTo: true },
// goJS('Shape', {
// stroke: '#2D9945',
// strokeWidth: 2,
// }),
// ),
// );
const fromJson = JSON.parse(jsonStr);
// const setTime = setTimeout(() => {
myTimeout(() => {
loop();
waterSvg();
......@@ -2192,7 +2179,7 @@ const ConfigurationView = (props) => {
okText={'确定'}
width={modalWidth}
cancelText={'取消'}
visible={isModalVisible}
open={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
wrapClassName={classNames(`${prefixCls}-baseModal`)}
......@@ -2209,10 +2196,11 @@ const ConfigurationView = (props) => {
title={'权限认证'}
okText={'确定'}
cancelText={'取消'}
visible={isAuModalVisible}
open={isAuModalVisible}
onOk={handleAuOk}
onCancel={() => setIsAuModalVisible(false)}
getContainer={ConfigurationRef.current}
width={520}
wrapClassName={classNames(`${prefixCls}-baseModal`)}
>
<Form className={classNames('authorizeControlContent')} ref={AuthorFrom} name="loginForm">
......@@ -2220,7 +2208,7 @@ const ConfigurationView = (props) => {
<Input placeholder="请输入用户名" />
</Form.Item>
<Form.Item className={classNames('authorizeControlItem')} name="password" label="密码">
<Input placeholder="请输入密码" />
<Input.Password placeholder="请输入密码" />
</Form.Item>
</Form>
</Modal>
......@@ -2229,24 +2217,15 @@ const ConfigurationView = (props) => {
{isHIModalVisible && (
<Modal
centered
width={960}
width={1100}
footer={null}
visible={isHIModalVisible}
open={isHIModalVisible}
onOk={() => setIsHIModalVisible(false)}
onCancel={() => setIsHIModalVisible(false)}
getContainer={ConfigurationRef.current}
wrapClassName={classNames(`${prefixCls}-historyInfoModal`)}
>
<HistoryInfo
title={''}
tableProps={{ bordered: true, pagination: { pageSize: 20 } }}
historyInfoService={getHistoryInfo}
historyInfoParams={historyInfoParams}
dictionaryService={getDictionaryList}
dictionaryParams={
Object.keys(dictionaryParams).length ? dictionaryParams : { nodeID: 0 }
}
/>
<HistoryView deviceParams={historyInfoParams} />
</Modal>
)}
{/* 画板跳转 */}
......@@ -2285,7 +2264,6 @@ ConfigurationView.defaultProps = {
name: '',
devices: [],
deviceName: [],
dictionaryParams: {},
config: {},
isZoom: false,
flowShow: true,
......@@ -2295,7 +2273,6 @@ ConfigurationView.propTypes = {
name: PropTypes.string,
devices: PropTypes.array,
deviceName: PropTypes.array,
dictionaryParams: PropTypes.object,
config: PropTypes.object,
isZoom: PropTypes.bool,
flowShow: PropTypes.bool,
......
......@@ -120,6 +120,10 @@
align-items: center;
margin-bottom: 20px;
.@{ant-prefix}-row {
width: 100%;
}
.@{ant-prefix}-col.@{ant-prefix}-form-item-label {
margin-right: 10px;
......@@ -167,6 +171,10 @@
&:last-of-type {
margin-bottom: 0;
}
.@{ant-prefix}-input-password-icon.anticon {
color: #ffffff;
}
}
}
......
......@@ -2,6 +2,51 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.8...@wisdom-components/ec_historyview@1.4.9) (2023-02-01)
### Bug Fixes
- **EC_HistoryView:** 优化历史曲线多图表标题 ([863ce35](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/863ce357d4d8b7efe0d4bcdd2e98a9c23c70bbb0))
- **EC_HistoryView:** 优化历史曲线缺省页显示 ([af79398](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/af793980467f57e5f163dc5a4632e472d6b9cdf8))
## [1.4.8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.5...@wisdom-components/ec_historyview@1.4.8) (2023-01-12)
### Bug Fixes
- 修改 ([a4b96b3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/a4b96b3061e5116ae3ae0c0647a4e049f6145315))
## [1.4.5](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.4...@wisdom-components/ec_historyview@1.4.5) (2023-01-12)
### Bug Fixes
- **EC_HistoryView:** 优化多图表图例显示 ([af874e6](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/af874e68ed6ee2614e8c0b39072182956339c5aa))
## [1.4.4](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.3...@wisdom-components/ec_historyview@1.4.4) (2023-01-12)
### Bug Fixes
- **EC_HistoryView:** 优化历史曲线图表居中及数据显示 ([b99aa64](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/b99aa64e817c77fa28ff0b3cb406290e9a40b59e))
## [1.4.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.2...@wisdom-components/ec_historyview@1.4.3) (2022-12-30)
**Note:** Version bump only for package @wisdom-components/ec_historyview
## [1.4.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.1...@wisdom-components/ec_historyview@1.4.2) (2022-12-29)
### Bug Fixes
- 优化历史曲线指标分组及排序 ([ebcef43](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/ebcef43e77b09387f6783bf9488269766bf029ca))
### Performance Improvements
- 优化历史曲线组件添加缺省页 ([b50bc3d](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/b50bc3dba8f6eb5ea2c652a984e299072695f5b3))
## [1.4.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.4.0...@wisdom-components/ec_historyview@1.4.1) (2022-12-21)
### Bug Fixes
- 修复历史曲线图表尺寸显示 ([b8a7081](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/b8a70811950606392864f243427d80f1bd54987d))
# [1.4.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_historyview@1.3.0...@wisdom-components/ec_historyview@1.4.0) (2022-12-19)
### Features
......
{
"name": "@wisdom-components/ec_historyview",
"version": "1.4.0",
"version": "1.4.9",
"description": "> TODO: description",
"author": "cuijiahao <15927252954@163.com>",
"homepage": "",
......
import React, { memo, useMemo } from 'react';
import _ from 'lodash';
import { BasicChart } from '@wisdom-components/basicchart';
import PandaEmpty from '@wisdom-components/empty';
import optionGenerator from './utils';
const ChartTitle = ({ prefixCls, title, unit }) => {
const cls = `${prefixCls}-grid-item-title`;
return (
<div className={cls}>
<span className={`${cls}_text`}>{title}</span>
{unit && <span className={`${cls}_unit`}>(单位:{unit}</span>}
</div>
);
};
const GridChart = memo((props) => {
const { dataSource, contrast = false, contrastOption = 'day', smooth = true } = props;
const {
dataSource,
contrast = false,
contrastOption = 'day',
smooth = true,
curveCenter,
} = props;
const { prefixCls } = props;
const gridData = useMemo(() => {
const grids = dataSource.reduce((pre, item, index) => {
const { sensorName } = item;
let grid = pre.find((g) => g.key === sensorName);
const { sensorName, deviceType } = item;
const key = `${deviceType}_${sensorName}`; // 同设备类型同指标才在同一组
let grid = pre.find((g) => g.key === key);
if (!grid) {
const restProp = _.pick(item, ['equipmentName', 'sensorName', 'stationCode', 'unit']);
grid = {
key: sensorName,
key: key,
list: [],
...restProp,
};
......@@ -32,28 +50,58 @@ const GridChart = memo((props) => {
const cusOption = {
title: {
show: true,
text: `{prefix|}{t|${sensorName}}${unit ? '{suffix|(单位:' + unit + ')}' : ''}`,
// text: `{prefix|}{t|${sensorName}}${unit ? '{suffix|(单位:' + unit + ')}' : ''}`,
text: ' ',
textStyle: {
width: 200,
overflow: 'truncate',
},
},
legend: {
// orient: 'vertical',
itemGap: 10,
padding: [0, 0, 0, 200],
textStyle: {
width: 120,
overflow: 'truncate',
},
},
};
const option = optionGenerator(list, cusOption, contrast, contrastOption, smooth);
const option = optionGenerator(list, cusOption, contrast, contrastOption, smooth, {
curveCenter,
nameWithSensor: false,
});
return {
key,
option: option,
};
});
}, [gridData, smooth]);
}, [gridData, smooth, curveCenter]);
return (
<div className={`${prefixCls}-grid`}>
{
options.map(item => (
{options.map((item, index) => {
const { sensorName, unit } = gridData[index];
const isEmpty =
!item.option.series.length ||
!item.option.series.find((e) => e.data && e.data.length > 0);
return (
<div key={item.key} className={`${prefixCls}-grid-item`}>
<div className={`${prefixCls}-grid-item-wrap`}>
<BasicChart style={{ width: '100%', height: '100%' }} option={item.option} notMerge />
<ChartTitle prefixCls={prefixCls} title={sensorName} unit={unit} />
{isEmpty ? (
<PandaEmpty />
) : (
<BasicChart
style={{ width: '100%', height: '100%' }}
option={item.option}
notMerge
/>
)}
</div>
</div>
))
}
);
})}
</div>
);
});
......
import React, { memo, useMemo } from 'react';
import React, { memo, useEffect, useMemo, useRef } from 'react';
import { BasicChart } from '@wisdom-components/basicchart';
import PandaEmpty from '@wisdom-components/empty';
import optionGenerator from './utils';
const SimgleChart = memo((props) => {
const { dataSource, contrast = false, contrastOption = 'day', smooth = true } = props;
const {
dataSource,
contrast = false,
contrastOption = 'day',
smooth = true,
curveCenter,
} = props;
const chartRef = useRef();
const option = useMemo(() => {
const config = {
needUnit: true,
curveCenter,
};
return optionGenerator(dataSource, null, contrast, contrastOption, smooth, config);
}, [dataSource, smooth]);
}, [dataSource, smooth, curveCenter]);
useEffect(() => {
chartRef.current?.resize?.();
}, []);
// 数据都为空显示缺省页
const isEmpty = useMemo(
() =>
!dataSource ||
!dataSource.length ||
!dataSource.find((e) => e.dataModel && e.dataModel.length > 0),
[dataSource],
);
return <BasicChart option={option} notMerge style={{ width: '100%', height: '100%' }}/>
return isEmpty ? (
<PandaEmpty />
) : (
<BasicChart ref={chartRef} option={option} notMerge style={{ width: '100%', height: '100%' }} />
);
});
export default SimgleChart;
\ No newline at end of file
export default SimgleChart;
import React from 'react';
import HistoryView from '../index';
const deviceParams = [{
deviceCode: "EGBF00000146",
sensors: "进水压力,出水瞬时流量,出水累计流量",
deviceType: "二供泵房"
}]
const deviceParams = [
{
deviceCode: 'EGBF00000146',
sensors: '进水压力,出水瞬时流量,出水累计流量',
deviceType: '二供泵房',
},
{
deviceCode: 'EGBF00000001',
sensors: '进水压力,出水瞬时流量,出水累计流量',
deviceType: '二供泵房',
},
{
deviceCode: 'EGBF00000002',
sensors: '进水压力,出水瞬时流量,出水累计流量',
deviceType: '二供泵房',
},
];
const Demo = () => {
return (
<div style={{height: 700}}>
<div style={{ height: 700 }}>
<HistoryView deviceParams={deviceParams} grid />
</div>
);
......
import React from 'react';
import HistoryView from '../index';
const deviceParams = [{
deviceCode: "EGBF00000146",
sensors: "进水压力,出水瞬时流量,出水累计流量",
deviceType: "二供泵房"
}]
const deviceParams = [
{
deviceCode: 'EGBF00000146',
sensors: '进水压力,出水瞬时流量,出水累计流量',
deviceType: '二供泵房',
},
{
deviceCode: 'EGJZ00001113',
sensors: '出水瞬时流量,出水压力,泵1状态',
deviceType: '二供机组',
},
];
const Demo = () => {
return (
<div style={{height: 700}}>
<div style={{ height: 700 }}>
<HistoryView deviceParams={deviceParams} />
</div>
);
......
......@@ -6,6 +6,7 @@ import { CloseCircleFilled, DownloadOutlined, PlusCircleOutlined } from '@ant-de
import moment from 'moment';
import _ from 'lodash';
import TimeRangePicker from '@wisdom-components/timerangepicker';
import PandaEmpty from '@wisdom-components/empty';
import BasicTable from '@wisdom-components/basictable';
import { getHistoryInfo } from './apis';
import SimgleChart from './SingleChart';
......@@ -110,6 +111,7 @@ const timeIntervalList = [
const updateTime = (key) => {
let start = '';
let end = '';
if (Array.isArray(key)) {
start = moment(key[0]).format(timeFormat);
end = moment(key[1]).format(timeFormat);
......@@ -174,7 +176,7 @@ const timeColumn = {
title: '采集时间',
dataIndex: 'time',
key: 'time',
width: 160,
width: 170,
fixed: 'left',
ellipsis: true,
align: 'center',
......@@ -312,7 +314,7 @@ const HistoryView = (props) => {
const renderTimeOption = () => {
return (
<div className={classNames(`${prefixCls}-date`)}>
<div className={classNames(`${prefixCls}-label`)}>时间</div>
<div className={classNames(`${prefixCls}-label`)}>时间选择</div>
<Radio.Group value={timeValue} onChange={onTimeSetChange}>
<Radio.Button value="customer">自定义</Radio.Button>
<Radio.Button value="contrast">同期对比</Radio.Button>
......@@ -459,7 +461,7 @@ const HistoryView = (props) => {
const obj = { key: time, time: time };
data.forEach((item, index) => {
const dataIndex = dataIndexAccess(item, index);
obj[dataIndex] = '--';
obj[dataIndex] = '';
});
return obj;
};
......@@ -485,7 +487,7 @@ const HistoryView = (props) => {
const formatTime = moment(value.pt).format(format);
const dataRow = timeData[formatTime];
if (dataRow) {
dataRow[dataIndex] = value.pv === null ? '--' : value.pv;
dataRow[dataIndex] = value.pv === null || value.pv === undefined ? '' : value.pv;
}
});
});
......@@ -532,7 +534,19 @@ const HistoryView = (props) => {
d.dateFrom = dateFrom;
d.dateTo = dateTo;
});
data = data.concat(res.data);
deviceParams.forEach((p) => {
// 返回数据按查询指标顺序排序
const sensors = p.sensors?.split(',') ?? [];
const list = sensors.map((s) => {
const dataItem = res.data.find(
(d) => d.stationCode === p.deviceCode && d.sensorName === s,
);
dataItem.dateFrom = dateFrom;
dataItem.dateTo = dateTo;
return dataItem;
});
data = data.concat(list);
});
}
});
setLoading(false);
......@@ -580,8 +594,11 @@ const HistoryView = (props) => {
{renderCurveOption()}
</div>
<div className={`${prefixCls}-content`}>
{grid === true ? (
{!chartDataSource.length ? (
<PandaEmpty />
) : grid === true ? (
<GridChart
curveCenter={curveCenter}
prefixCls={prefixCls}
dataSource={chartDataSource}
contrast={timeValue === 'contrast'}
......@@ -589,6 +606,7 @@ const HistoryView = (props) => {
/>
) : (
<SimgleChart
curveCenter={curveCenter}
prefixCls={prefixCls}
dataSource={chartDataSource}
contrast={timeValue === 'contrast'}
......@@ -603,15 +621,17 @@ const HistoryView = (props) => {
{renderCurveOption()}
</div>
<div className={`${prefixCls}-content`}>
{
{chartDataSource.length > 0 ? (
<BasicTable
dataSource={tableData}
columns={columns}
{...tableProps}
pagination={{ showQuickJumper: true, showSizeChanger: true }}
pagination={false}
onChange={() => {}}
/>
}
) : (
<PandaEmpty />
)}
</div>
</Tabs.TabPane>
</Tabs>
......
......@@ -4,6 +4,7 @@
.@{history-view} {
height: 100%;
padding: @padding-md;
&-label {
position: relative;
......@@ -17,6 +18,11 @@
}
}
.@{ant-prefix}-tabs-extra-content {
width: 82px;
white-space: nowrap;
}
&-extra-right {
width: 82px;
}
......@@ -40,14 +46,6 @@
align-items: center;
white-space: nowrap;
.@{history-view}-label {
letter-spacing: 27px;
&::after {
right: -20px;
}
}
.@{ant-prefix}-radio-group,
.@{ant-prefix}-select {
margin-right: 16px;
......@@ -59,8 +57,6 @@
font-size: 16px;
cursor: pointer;
}
}
.@{history-view}-contrast {
......@@ -99,11 +95,11 @@
.@{history-view}-options {
display: flex;
align-items: center;
flex-wrap: wrap;
align-items: center;
padding-bottom: 10px;
column-gap: 20px;
row-gap: 10px;
padding-bottom: 10px;
}
.@{history-view}-cover {
......@@ -113,26 +109,70 @@
}
.@{history-view}-content {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
overflow: hidden;
}
.@{history-view}-grid {
height: 100%;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
background-color: #F0F2F5;
width: 100%;
height: 100%;
padding: 4px;
overflow-y: auto;
background-color: #f0f2f5;
&-item {
width: 50%;
height: 50%;
padding: 4px;
&-title {
position: absolute;
top: 16px;
left: 20px;
z-index: 2;
max-width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&::before {
display: inline-block;
width: 5px;
height: 16px;
vertical-align: -0.2em;
background-color: #1685ff;
content: '';
}
&_text {
padding-left: 10px;
color: '#333333';
font-weight: bold;
font-size: 15px;
font-family: 'Microsoft YaHei';
}
&_unit {
padding-left: 5px;
color: #999999;
font-size: 12px;
}
}
}
&-item-wrap {
height: 350px;
background-color: #FFF;
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
overflow: hidden;
background-color: #fff;
border-radius: 4px;
}
}
\ No newline at end of file
}
import moment from 'moment';
import _ from 'lodash';
/**
* 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸
*/
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const axisWidth = 40;
/**
* 图表系列名称格式化
* @param {*} data
*
* @param {any} data
* @param {boolean} contrast 是否为同期对比
* @param {*} contrastOption 同期对比周期配置, day|month
* @returns
* @param {any} contrastOption 同期对比周期配置, day|month
* @returns
*/
const nameFormatter = (data, contrast, contrastOption) => {
const nameFormatter = (data, contrast, contrastOption, nameWithSensor) => {
const { equipmentName, sensorName, unit, dataModel, dateFrom, dateTo } = data;
let name = `${equipmentName}-${sensorName}`;
let name = nameWithSensor ? `${equipmentName}-${sensorName}` : equipmentName;
if (contrast) {
const time = dateFrom.slice(0, contrastOption === 'day' ? 10 : 7).replace(/-/g, '');
name = `${name}-${time}`;
......@@ -25,15 +24,16 @@ const nameFormatter = (data, contrast, contrastOption) => {
/**
* 图表系列数据格式化
* @param {*} data
*
* @param {any} data
* @param {boolean} contrast 是否为同期对比
* @param {*} contrastOption 同期对比周期配置, day|month
* @param {any} contrastOption 同期对比周期配置, day|month
* @returns 图表系列数据, [[DateTime, value]]
*/
const dataAccessor = (data, contrast, contrastOption) => {
const { dataModel } = data;
const formatStr = contrastOption === 'day' ? '2020-01-01 HH:mm:00' : '2020-01-DD HH:mm:00';
return dataModel.map(item => {
return dataModel.map((item) => {
const time = contrast ? moment(item.pt).format(formatStr) : item.pt;
return [moment(time).valueOf(), item.pv];
});
......@@ -41,28 +41,48 @@ const dataAccessor = (data, contrast, contrastOption) => {
/**
* 面积图配置(目前默认曲线图)
* @param {*} data 数据项
* @returns null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
*
* @param {any} data 数据项
* @returns Null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
*/
const areaStyleFormatter = (data) => {
const { sensorName } = data;
return sensorName && sensorName.indexOf('流量') > -1 ? {} : null;
};
/**
* 数据项中指标值最小最大值
*
* @param {any} data 数据项
* @returns
*/
const minMax = (data) => {
const { dataModel } = data;
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
dataModel.forEach((item) => {
min = Math.min(min, item.pv ?? 0);
max = Math.max(max, item.pv ?? 0);
});
return [min, max];
};
/**
* 图表配置项生成
* @param {*} dataSource 数据源
* @param {*} cusOption 自定义属性
* @param {*} contrast 是否为同期对比
* @param {*} contrastOption 同期对比周期配置, day|month
* @param {*} smooth ture/false, 曲线/折线
* @param {*} config 额外配置信息
*
* @param {any} dataSource 数据源
* @param {any} cusOption 自定义属性
* @param {any} contrast 是否为同期对比
* @param {any} contrastOption 同期对比周期配置, day|month
* @param {any} smooth Ture/false, 曲线/折线
* @param {any} config 额外配置信息
*/
const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth, config) => {
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
// 自定义属性
const restOption = _.pick(cusOption, ['title',]);
const restOption = _.pick(cusOption, ['title', 'legend']);
// 一种指标一个y轴
const yAxisMap = new Map();
......@@ -78,17 +98,25 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
position: i % 2 === 0 ? 'left' : 'right',
offset: Math.floor(i / 2) * axisWidth,
axisLabel: {
formatter: (value) => value > 100000 ? `${value / 1000}k` : value,
formatter: (value) => (value > 100000 ? `${value / 1000}k` : value),
},
axisLine: {
show: true,
},
nameTextStyle: {
align: i % 2 === 0 ? 'right' : 'left'
align: i % 2 === 0 ? 'right' : 'left',
},
}
};
yAxisMap.set(key, axis);
}
// 曲线居中
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
const [min, max] = minMax(item);
const axis = yAxisMap.get(key);
axis.min = axis.min === void 0 ? min : Math.min(min, axis.min);
axis.max = axis.max === void 0 ? max : Math.max(max, axis.max);
}
});
const yAxis = yAxisMap.size > 0 ? [...yAxisMap.values()] : { type: 'value' };
......@@ -105,14 +133,13 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
const yAxisInterator = (() => {
const map = new Map();
let current = -1;
const get = (name) => map.has(name) ? map.get(name) : map.set(name, ++current).get(name);
return { get }
const get = (name) => (map.has(name) ? map.get(name) : map.set(name, ++current).get(name));
return { get };
})();
const series = dataSource.map(item => {
const series = dataSource.map((item) => {
const { sensorName, unit } = item;
const name = nameFormatter(item, contrast, contrastOption);
const name = nameFormatter(item, contrast, contrastOption, nameWithSensor);
const data = dataAccessor(item, contrast, contrastOption);
const type = 'line';
const areaStyle = areaStyleFormatter(item);
......@@ -126,18 +153,27 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
yAxisIndex,
smooth,
unit,
}
};
});
// 由于series更新后,没有的数据曲线仍然停留在图表区上,导致图表可视区范围有问题
const min = Math.min(...series.map(item => item.data?.[0]?.[0]).filter(item => item !== undefined));
const max = Math.max(...series.map(item => item.data?.[item.data.length - 1]?.[0]).filter(item => item !== undefined));
const min = Math.min(
...series.map((item) => item.data?.[0]?.[0]).filter((item) => item !== undefined),
);
const max = Math.max(
...series
.map((item) => item.data?.[item.data.length - 1]?.[0])
.filter((item) => item !== undefined),
);
const xAxis = { type: 'time', min, max };
const tooltipTimeFormat = !contrast ? 'YYYY-MM-DD HH:mm:ss' : contrastOption === 'day' ? 'HH:mm' : 'DD HH:mm';
const tooltipTimeFormat = !contrast
? 'YYYY-MM-DD HH:mm:ss'
: contrastOption === 'day'
? 'HH:mm'
: 'DD HH:mm';
const tooltip = { timeFormat: tooltipTimeFormat };
return {
yAxis,
grid,
......@@ -145,7 +181,7 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
series,
tooltip,
...restOption,
}
};
};
export default optionGenerator;
......@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.17](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_quotaselect@1.3.16...@wisdom-components/ec_quotaselect@1.3.17) (2023-02-02)
### Bug Fixes
- **EC_QuotaSelect:** 修复指标选择器用户配置 ([62f05e5](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/62f05e5f537cb44a2626a097ebde9b510b056a0d))
## [1.3.16](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_quotaselect@1.3.15...@wisdom-components/ec_quotaselect@1.3.16) (2022-12-20)
### Bug Fixes
......
{
"name": "@wisdom-components/ec_quotaselect",
"version": "1.3.16",
"version": "1.3.17",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
......
......@@ -59,10 +59,14 @@ const QuotaSelect = ({
const fetchData = (item = {}) => {
// 请求指标列表
getQuataList({
accountName: item.deviceType,
addrSchemeID: item.pointAddressID,
}).then((res) => {
getQuataList(
Object.assign(
{
accountName: item.deviceType,
},
user ? { user } : { addrSchemeID: item.pointAddressID },
),
).then((res) => {
if (res.code === 0) {
const data =
res.data.length > 0
......
......@@ -2,6 +2,16 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.16](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_realtimeinfo@1.4.15...@wisdom-components/ec_realtimeinfo@1.4.16) (2023-01-10)
**Note:** Version bump only for package @wisdom-components/ec_realtimeinfo
## [1.4.15](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_realtimeinfo@1.4.14...@wisdom-components/ec_realtimeinfo@1.4.15) (2023-01-09)
### Bug Fixes
- **EC_RealTimeInfo:** 组件服务优化 ([a08bd4f](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/a08bd4fb5ec887d84e8efd7253cf1a6f0663f963))
## [1.4.14](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_realtimeinfo@1.4.13...@wisdom-components/ec_realtimeinfo@1.4.14) (2022-06-02)
### Bug Fixes
......
{
"name": "@wisdom-components/ec_realtimeinfo",
"version": "1.4.14",
"version": "1.4.16",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
......
import { request } from '@wisdom-utils/utils';
const REQUEST_METHOD_GET = 'get';
const REQUEST_METHOD_POST = 'post';
// eslint-disable-next-line no-undef
const baseUrl = typeof DUMI_TYPE !== 'undefined' && DUMI_TYPE === 'dumi' ? '/api' : '';
// 获取监控展示配置
export function getMonitorConfig({ params, data } = {}) {
return request({
url: `/PandaMonitor/Monitor/MonitorConfig/GetMonitorConf`,
method: REQUEST_METHOD_GET,
params,
data,
});
}
// 获取传感器类型
export function getSensorType({ params, data } = {}) {
return request({
url: `/PandaCore/GCK/Sensor/GetSensorType`,
method: REQUEST_METHOD_GET,
params,
data,
});
}
// 获取设备实时数据
export function getDeviceRealInfo({ params, data } = {}) {
return request({
url: `/PandaMonitor/Monitor/Device/GetDeviceRealInfo`,
method: REQUEST_METHOD_POST,
params,
data,
});
}
// 获取点表地址
export function getPointAddressEntry({ params, data } = {}) {
return request({
url: `/PandaMonitor/Monitor/PointAddress/GetPointAddressEntry`,
method: REQUEST_METHOD_GET,
params,
data,
});
}
// 获取点表版本
export function getPointAddress({ params, data } = {}) {
return request({
url: `/PandaMonitor/Monitor/PointAddress/GetPointAddress`,
method: REQUEST_METHOD_GET,
params,
data,
});
}