Commit 84d46bf1 authored by 邓晓峰's avatar 邓晓峰

feat: add notifier

parent 0596fdd5
Pipeline #47274 skipped with stages
......@@ -110,7 +110,7 @@
"@wisdom-map/Map": "^1.0.12-17",
"@wisdom-map/arcgismap": "^1.0.79-17",
"@wisdom-map/util": "^1.0.27-0",
"@wisdom-utils/components": "0.0.29",
"@wisdom-utils/components": "0.0.31",
"@wisdom-utils/runtime": "0.0.15",
"@wisdom-utils/utils": "0.0.77",
"animate.css": "^4.1.1",
......
......@@ -19,7 +19,6 @@ export default {
const options = {
newColors: this.getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors`
changeUrl(cssUrl) {
console.log("cssUrl", cssUrl);
return `/${pkg.name.toLowerCase()}/${cssUrl}`; // while router is not `hash` mode, it needs absolute path
},
};
......
......@@ -5,9 +5,9 @@ import { connect } from 'react-redux';
import Icon from '@ant-design/icons';
import classNames from 'classnames';
import { useHistory } from '@wisdom-utils/runtime';
import { HeaderSearch } from '@wisdom-utils/components';
import { useIntl } from '@/locales/localeExports';
import { actionCreators } from '../../containers/App/store';
import { HeaderSearch } from '@wisdom-utils/components';
import Avatar from './AvatarDropdown';
import styles from './index.less';
import NoticeIconView from './NoticeIconView';
......
......@@ -2,14 +2,21 @@ import React, { Component } from 'react';
import { Button, Form, Input, Modal } from 'antd';
import { connect } from 'react-redux';
import { Notifier, NoticeIcon } from '@wisdom-utils/components';
import {
ERR_OK,
MESSAGE_TYPE,
NEW_MESSAGE,
} from '@wisdom-utils/components/lib/AppLayout/notifier/constants';
import {
findPathByWidget,
isJSON,
} from '@wisdom-utils/components/lib/AppLayout/helpers';
import { FormattedMessage } from '@/locales/localeExports';
import service from '../../api/service/notification';
import { actionCreators } from '../../containers/App/store';
import isProd from '../../utils/env';
import { findPathByWidget, isJSON } from '../../utils/utils';
import NoticeIcon from '../NoticeIcon';
import Notifier from '../Notifier';
import { ERR_OK, MESSAGE_TYPE, NEW_MESSAGE } from '../Notifier/constants';
// import NoticeIcon from '../NoticeIcon';
import styles from './index.less';
const { TextArea } = Input;
......
......@@ -4,10 +4,10 @@ import { message } from 'antd';
import _ from 'lodash';
import { connect } from 'react-redux';
import Icon from '@ant-design/icons';
import { HeaderSearch } from '@wisdom-utils/components';
import { useIntl } from '@/locales/localeExports';
import { actionCreators } from '../../containers/App/store';
import { HeaderSearch } from '@wisdom-utils/components';
import Avatar from './AvatarDropdown';
import styles from './index.less';
import NoticeIconView from './NoticeIconView';
......
import React from 'react';
import {
List,
Spin,
} from 'antd';
import classNames from 'classnames';
import styles from './NoticeList.less';
import Alarm from './Templates/Alarm';
import Case from './Templates/Case';
import Notice from './Templates/Notice';
import Unknown from './Templates/Unknown';
const Empty = ({ emptyText }) => (
<div className={styles.notFound}>
<img
src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
alt="not found"
/>
<div>{emptyText}</div>
</div>
);
class NoticeList extends React.Component {
constructor(props) {
super(props);
this.emptyText = props.emptyText;
this.confirmRead = props.confirmRead;
this.handlerSysDetail = props.handlerSysDetail;
this.loadMore = props.loadMore;
this.hasMore = props.hasMore;
this.container = React.createRef();
this.state = {
isLoading: false,
};
this.mounted = false;
this.handleScrollCallback = this.throttle(
this.handleScroll.bind(this),
30,
).bind(this);
}
componentDidMount() {
this.mounted = true;
if (this.container.current) {
this.container.current.addEventListener(
'scroll',
this.handleScrollCallback,
);
}
}
componentWillUnmount() {
this.mounted = false;
}
throttle(fn, wait) {
/* eslint-disable */
let pre = Date.now();
return function() {
const context = this;
// eslint-disable-next-line prefer-rest-params
const args = arguments;
const now = Date.now();
if (now - pre >= wait) {
fn.apply(context, args);
pre = Date.now();
}
};
}
handleScroll(e) {
e.stopPropagation();
if (!this.mounted) return;
if (!this.container.current) return;
const { current } = this.container;
if (
current.scrollHeight - current.scrollTop - current.offsetHeight <=
100
) {
this.handleLoadMore();
}
}
handleLoadMore() {
if (this.state.isLoading) return;
if (!this.hasMore()) return;
this.setState(
{
isLoading: true,
},
() => {
if (!this.loadMore) return;
this.loadMore().then(data => {
if (!this.mounted) return;
this.setState({
isLoading: false,
});
});
},
);
}
render() {
if (!this.props.data || this.props.data.length === 0) {
return <Empty emptyText={this.emptyText} />;
}
return (
<div className={styles.container} ref={this.container}>
<List
className={styles.list}
dataSource={this.props.data}
renderItem={(item, i) => {
const itemCls = classNames(styles.item, {
[styles.read]: item.read,
});
let messageTemplate = <></>;
switch (item.infoType) {
case 'scadaType':
messageTemplate = (
<Alarm message={item} confirmRead={this.confirmRead} config={this.props.config} />
);
break;
case 'caseType':
messageTemplate = (
<Case message={item} confirmRead={this.confirmRead} />
);
break;
case 'sysType':
messageTemplate = (
<Notice message={item} confirmRead={this.confirmRead} config={this.props.config} handlerSysDetail={this.handlerSysDetail}/>
);
break;
default:
messageTemplate = (
<Unknown message={item} confirmRead={this.confirmRead} />
);
break;
}
return (
<List.Item className={itemCls} key={item.id || i}>
{messageTemplate}
</List.Item>
);
}}
/>
<div className={styles.bottomBar}>
{this.state.isLoading ? (
<>
<Spin /> 加载中...
</>
) : this.hasMore() ? (
<span>下拉加载更多</span>
) : (
<span style={{fontSize: '12px', color: 'rgba(0, 0, 0, 0.6)'}}>已经没有更多消息了</span>
)}
</div>
</div>
);
}
}
export default NoticeList;
@import '~antd/es/style/themes/default.less';
.container {
max-height: 400px;
overflow: auto;
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background: rgba(0, 0, 0, 0.1);
-webkit-box-shadow: inset 0 0 6px rgba(177, 177, 177, 0.5);
box-shadow: inset 0 0 6px rgba(177, 177, 177, 0.5);
}
&::-webkit-scrollbar-track {
/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 6px rgba(193, 193, 193, 0.3);
box-shadow: inset 0 0 6px rgba(193, 193, 193, 0.3);
border-radius: 10px;
}
.list {
.item {
overflow: hidden;
padding: 0px;
cursor: pointer;
.meta {
width: 100%;
}
&:hover {
background-color: @primary-1;
}
&:last-child {
border-bottom: 0;
}
}
}
.bottomBar {
height: 46px;
color: @text-color;
line-height: 46px;
text-align: center;
transition: all 0.3s;
}
}
.notFound {
padding: 73px 0 88px;
color: @text-color-secondary;
text-align: center;
border-radius: 0 !important;
img {
display: inline-block;
height: 76px;
margin-bottom: 16px;
}
}
.notFound {
padding: 73px 0 88px;
color: @text-color-secondary;
text-align: center;
border-radius: 0 !important;
img {
display: inline-block;
height: 76px;
margin-bottom: 16px;
}
}
import React from 'react';
import _ from 'lodash';
import classNames from 'classnames';
import { findPathByWidget, isJSON } from '../../../../utils/utils';
import commonStyles from '../common.less';
import styles from './index.less';
/* eslint-disable */
export class AlarmContent {
constructor({
alarmType,
deviceCode,
alarmDevice,
alarmContent,
alarmValue,
alarmThreshold,
time,
} = content) {
this.alarmType = alarmType;
this.deviceCode = deviceCode;
this.alarmDevice = alarmDevice;
this.alarmContent = alarmContent;
this.alarmValue = alarmValue;
this.alarmThreshold = alarmThreshold;
this.time = time;
}
}
const Alarm = ({ message, confirmRead, config }) => {
const alarmContent = (config.mqtt_mess.MessageLevel === "2.0" && isJSON(message.infoContent)) ? JSON.parse(message.infoContent): message.infoContent;
const goPath = item => {
confirmRead(false, [message.id]);
const widgetID = 'widget_city_综合运营_管网监控_实时监控_报警监控';
const webPath = 'product/scada/AlertMonitoring/AlertMonitoring';
const widget = findPathByWidget("productex/water/IOTMonitor/RealTimeAlarm/RealTimeAlarm", config.widgets, "", "url");
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label: '实时报警',
url: widget.url || webPath,
});
};
const alarmValue = alarmContent && alarmContent.alarmValue && alarmContent.alarmValue.split(' ');
let alarmTitle = alarmContent && alarmContent.title && alarmContent.title.split(' ') || alarmContent.alarmDevice;
alarmTitle = Array.isArray(alarmTitle) ? alarmTitle[1]: alarmTitle;
return (
<div
className={classNames(styles.scada, commonStyles.messageContainer)}
title="点击查看详情"
onClick={() => goPath(message)}
>
<div className={commonStyles.title}>
<span>消息</span>
<img
className={commonStyles.confirm}
title="点击标为已读"
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
alt=""
src="https://panda-water.cn/Web4/assets/images/message/%E5%8B%BE%E6%B5%85.png"
/>
</div>
<div className={commonStyles.content}>
<p>
<i>{alarmContent.alarmType}</i>
{alarmTitle}
</p>
<p style={{color: '#888'}}>{alarmContent.alarmContent}</p>
<p style={{color: '#888'}} >
{
alarmContent && _.isString(alarmContent.content) && alarmContent.content.split(",")[1]
}
</p>
<p className={commonStyles.messageTime}>{message.time}</p>
</div>
</div>
);
};
export default Alarm;
.scada {
background: url(https://panda-water.cn/Web4/assets/images/message/%E6%B6%88%E6%81%AF.png)
16px 10px no-repeat;
}
import React from 'react';
import classNames from 'classnames';
import commonStyles from '../common.less';
import styles from './index.less';
// "caseType":"待办工单","flowName":"维修处理流程","nodeName":"审核关单","content":"请迅速到现场处理","time":"2020-11-03 09:11:12"
export class CaseContent {
// eslint-disable-next-line no-use-before-define
constructor({ caseType, flowName, nodeName, content, time } = content) {
this.caseType = caseType;
this.flowName = flowName;
this.nodeName = nodeName;
this.content = content;
this.time = time;
}
}
const Case = ({ message, confirmRead }) => {
const caseContent = message.infoContent;
const goPath = item => {
confirmRead(false, [message.id]);
const messageType = item.messType;
let label = '';
let widgetID = '';
switch (messageType) {
case '任务派发':
label = '任务派发';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
case '任务驳回':
label = '任务驳回';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
// eslint-disable-next-line no-underscore-dangle,no-case-declarations
let _tab;
// eslint-disable-next-line prefer-const
_tab = '任务驳回';
break;
default:
label = '工单办理';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
}
const webPath =
item.webPath ||
'product/maintenance/CaseManage/CaseDoingBox/StardCaseDoingBoxView|isDelay=1';
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label,
url: webPath,
});
};
return (
<div
className={classNames(styles.case, commonStyles.messageContainer)}
title="点击查看详情"
onClick={() => goPath(message)}
>
<div className={commonStyles.title}>
<span>消息</span>
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<img
className={commonStyles.confirm}
title="点击标为已读"
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
src="https://panda-water.cn/Web4/assets/images/message/%E5%8B%BE%E6%B5%85.png"
/>
</div>
<div className={commonStyles.content}>
<p>
<i>{caseContent.caseType}</i>
{caseContent.flowName}
</p>
<p>
{caseContent.nodeName} : {caseContent.content}
</p>
<p className={commonStyles.messageTime}>{message.time}</p>
</div>
</div>
);
};
export default Case;
.case {
background: url(https://panda-water.cn/Web4/assets/images/message/%E6%B6%88%E6%81%AF.png)
16px 10px no-repeat;
}
import React from 'react';
import classNames from 'classnames';
import { isJSON } from '../../../../utils/utils';
import commonStyles from '../common.less';
import styles from './index.less';
export class NoticeContent {
// eslint-disable-next-line no-undef
constructor({ noticeTitle, noticeType, noticeContent, time } = content) {
this.noticeTitle = noticeTitle;
this.noticeType = noticeType;
this.noticeContent = noticeContent;
this.time = time;
}
}
const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
// eslint-disable-next-line no-debugger
const noticeContent =
config.mqtt_mess.MessageLevel === '2.0' && isJSON(message.infoContent)
? JSON.parse(message.infoContent)
: message.infoContent;
const goPath = item => {
// eslint-disable-next-line no-debugger
// eslint-disable-next-line no-debugger
confirmRead(false, [message.id]);
handlerSysDetail && handlerSysDetail(message);
};
return (
<div
className={classNames(styles.notice, commonStyles.messageContainer)}
title="点击查看详情"
onClick={() => goPath(message)}
>
<div className={commonStyles.title}>
<span>公告</span>
<img
className={commonStyles.confirm}
title="点击标为已读"
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
src="https://panda-water.cn/Web4/assets/images/message/%E5%8B%BE%E6%B5%85.png"
alt=""
/>
</div>
<div className={commonStyles.content}>
<p>
<i>{noticeContent.noticeType}</i>
{noticeContent.noticeTitle}
</p>
{/* eslint-disable-next-line react/no-danger */}
<p dangerouslySetInnerHTML={{ __html: noticeContent.noticeContent }} />
<p className={commonStyles.messageTime}>{message.time}</p>
</div>
</div>
);
};
export default Notice;
.notice {
background: url(https://panda-water.cn/Web4/assets/images/message/%E6%B6%88%E6%81%AF.png)
16px 10px no-repeat;
}
import React from 'react';
import classNames from 'classnames';
import commonStyles from '../common.less';
import styles from './index.less';
const Unknown = ({ message, confirmRead }) => {
let content = '';
try {
const type = typeof message.infoContent;
switch (type) {
case 'object':
content = JSON.stringify(message.infoContent);
break;
case 'string':
content = message.infoContent;
break;
default:
break;
}
} catch (e) {
// i
}
return (
<div
className={classNames(styles.unknown, commonStyles.messageContainer)}
title="点击查看详情"
>
<div className={commonStyles.title}>
<span>消息</span>
<img
className={commonStyles.confirm}
title="点击标为已读"
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
src="https://panda-water.cn/Web4/assets/images/message/%E5%8B%BE%E6%B5%85.png"
alt=""
/>
</div>
<div className={commonStyles.content}>
<p>{content}</p>
<p className={commonStyles.messageTime}>{message.time}</p>
</div>
</div>
);
};
export default Unknown;
.unknown {
background: url(https://panda-water.cn/Web4/assets/images/message/%E6%B6%88%E6%81%AF.png)
16px 10px no-repeat;
}
.messageContainer {
padding-left: 50px;
padding-right: 20px;
padding-top: 8px;
width: 100%;
.title {
display: flex;
justify-content: space-between;
span {
font-size: 16px;
color: #666;
font-weight: normal;
text-shadow: none;
letter-spacing: 0;
}
.confirm {
margin-right: 20px;
width: 20px;
height: 16px;
}
}
.content {
margin-top: 10px;
p {
i {
font-size: 14px;
text-shadow: none;
color: #000;
font-style: normal;
color: #1ba6f9;
margin-right: 10px;
}
margin-bottom: 3px;
font-size: 12px;
}
.messageTime {
float: right;
margin-right: 30px;
}
}
}
import React from 'react';
import { Badge } from 'antd';
import classNames from 'classnames';
import { connect } from 'react-redux';
import useMergeValue from 'use-merge-value';
import Icon from '@ant-design/icons';
import { HeaderDropdown } from '@wisdom-utils/components';
import styles from './index.less';
import NoticeList from './NoticeList';
const messageSvg = () => (
<svg
version="1.1"
x="0px"
y="0px"
width="24px"
height="24px"
viewBox="0 0 24 24"
enableBackground="new 0 0 24 24"
space="preserve"
>
<path
fill="hsla(221, 100%, 95%, 0.7)"
d="M20.486,16.373l-1.721-2.246v-0.984v-0.352V9.924c0-1.919-0.664-3.698-1.871-5.007
c-0.712-0.776-1.57-1.349-2.551-1.705c-0.091-0.514-0.35-0.983-0.737-1.335c-0.879-0.791-2.334-0.791-3.21,0
c-0.394,0.354-0.653,0.823-0.741,1.336C8.676,3.568,7.817,4.14,7.105,4.917C5.899,6.229,5.234,8.008,5.234,9.923l0.005,4.194
l-1.708,2.234c-0.241,0.256-0.372,0.584-0.372,0.932v1.092c0,0.75,0.615,1.357,1.372,1.357H19.47c0.757,0,1.371-0.607,1.371-1.357
v-1.092C20.841,16.936,20.71,16.607,20.486,16.373z M4.899,17.996v1.016l-0.001-2.061l1.628-2.154
c0.227-0.244,0.353-0.561,0.353-0.893v-4.05c0-1.516,0.509-2.914,1.436-3.935c0.459-0.506,1.001-0.895,1.608-1.166
c1.276-0.565,2.883-0.565,4.155,0c0.609,0.273,1.15,0.667,1.608,1.168c0.925,1.021,1.437,2.417,1.437,3.934v2.762v0.338v0.949
c0,0.334,0.123,0.654,0.336,0.875l1.642,2.164l0.013,1.037L4.899,17.996z"
/>
<path
fill="hsla(221, 100%, 95%, 0.7)"
d="M13.685,20.236c-0.101,0.238-0.248,0.453-0.444,0.631c-0.677,0.617-1.799,0.615-2.473,0.002
c-0.194-0.18-0.344-0.396-0.446-0.633H8.895c0.146,0.627,0.474,1.199,0.955,1.639c0.588,0.543,1.354,0.841,2.158,0.841
c0.801,0,1.566-0.298,2.154-0.837c0.481-0.439,0.808-1.012,0.954-1.641L13.685,20.236z"
/>
</svg>
);
const BellOutlined = props => <Icon component={messageSvg} {...props} />;
const NoticeIcon = props => {
const getNotificationBox = () => {
const { children, confirmRead } = props;
if (!children) {
return null;
}
const panes = [];
React.Children.forEach(children, child => {
if (!child) {
return;
}
const { list, title } = child.props;
panes.push(
<NoticeList
{...child.props}
data={list}
key={child}
title={title}
config={props.global}
/>,
);
});
const childProps = panes.length === 1 ? panes[0].props : { list: [] };
return (
<>
<div className={styles.header}>
<span className={styles.title}>通知</span>
<span
onClick={() =>
childProps.list.length > 0 ? confirmRead(true) : null
}
style={{
color: childProps.list.length === 0 && 'rgba(0, 0, 0, 0.5)',
}}
>
全部标记已读
</span>
</div>
{panes}
</>
);
};
const { className, bell } = props;
const [visible, setVisible] = useMergeValue(false, {
value: props.popupVisible,
onChange: props.onPopupVisibleChange,
});
const noticeButtonClass = classNames(className, styles.noticeButton);
const notificationBox = getNotificationBox();
const NoticeBellIcon = bell || (
<BellOutlined className={styles.icon} title="报警" />
);
const trigger = (
<span className={classNames(noticeButtonClass, { opened: visible })}>
<Badge
count={props.count}
overflowCount={99}
offset={[0, 8]}
style={{ boxShadow: 'none' }}
title="报警"
className={classNames(
styles.badge,
props.count > 0 ? styles.fountMessage : '',
)}
>
{NoticeBellIcon}
</Badge>
<span className={styles.title}>消息</span>
</span>
);
if (!notificationBox) {
return trigger;
}
return (
<>
<HeaderDropdown
placement="bottomRight"
overlay={notificationBox}
overlayClassName={styles.popover}
trigger={['click']}
visible={visible}
onVisibleChange={setVisible}
>
{trigger}
</HeaderDropdown>
</>
);
};
NoticeIcon.defaultProps = {
emptyImage:
'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
};
NoticeIcon.Tab = NoticeList;
const mapStateToProps = state => ({
global: state.getIn(['global', 'globalConfig']),
});
export default connect(
mapStateToProps,
null,
)(NoticeIcon);
@import '~antd/es/style/themes/default.less';
.popover {
position: absolute;
width: 336px;
z-index: 1100;
}
.noticeButton {
display: inline-block;
cursor: pointer;
transition: border-color 0.3s, background 0.3s, padding 0.1s cubic-bezier(0.215, 0.61, 0.355, 1);
.title {
color: hsla(221, 100%, 95%, 0.7);
}
&:hover {
.fountMessage {
svg {
path {
fill: #fff;
}
}
}
.title {
color: #fff;
}
}
}
.icon {
padding: 4px;
vertical-align: middle;
}
.badge {
font-size: 16px;
:global {
.@{ant-prefix}-badge-multiple-words {
padding: 0 4px;
}
}
&.fountMessage {
.icon {
animation: bellshake 2s ease-out infinite;
}
}
}
.tabs {
:global {
.@{ant-prefix}-tabs-nav-list {
margin: auto;
}
.@{ant-prefix}-tabs-nav-scroll {
text-align: center;
}
.@{ant-prefix}-tabs-bar {
margin-bottom: 0;
}
}
}
.header {
border-radius: 0 !important;
padding: 8px;
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-size: 16px;
font-weight: bold;
margin-left: 5px;
color: rgb(102, 102, 102);
}
span {
&:last-child {
cursor: pointer;
color: @primary-color;
font-size: 12px;
}
}
}
@keyframes bellshake {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
3.75% {
-webkit-transform: rotate(25deg);
transform: rotate(25deg);
}
15% {
-webkit-transform: rotate(-25deg);
transform: rotate(-25deg);
}
22.5% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg);
}
29% {
-webkit-transform: rotate(-10deg);
transform: rotate(-10deg);
}
35% {
-webkit-transform: rotate(5deg);
transform: rotate(5deg);
}
43% {
-webkit-transform: rotate(-2deg);
transform: rotate(-2deg);
}
50%,
to {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
export const REQUEST_SERVICE = {
EIMTopic: '/EIM/info',
SaveWaTopic: '/saveWater/info',
SystemTopic: '/system/info',
WorkerOrderTopic: '/workerOrder/info',
ScadaTopic: '/scada/alarm',
UserTopic: '/Message/',
};
export const MESSAGE_TYPE = {
SCADA_TYPE: 'scadaType',
CASE_TYPE: 'caseType',
SYS_TYPE: 'sysType',
SAVE_WA_TYPE: 'saveWaType',
EIMT_TYPE: 'EIMType',
MESSAGE_ALERT: 'remindType',
UNKNOWN: 'unknown',
};
export const NEW_MESSAGE = 'NEW_MESSAGE';
export const MESSAGE_TEXT_TYPE = {
PROJECT_FLOW: '工单流程',
SYS_MESSAGE: '系统消息',
SYS_NOTICE: '系统通知',
SAWATER: '节水通知',
EMTT: '信息化',
MESSAGE_ALERT: '消息提醒',
SCADA_ALARM: 'SCADA报警',
};
export const USERNAME = 'mao2080';
export const PASSWORD = '123';
export const PLATFORM_LEVEL = '4';
export const VIDEO_LEVEL = '5';
export const SYS_LEVEL = '6';
export const ERR_OK = '0000';
export const DEFAULT_TCP_PORT = 443;
export const DEFAULT_TCP_IP = 'emqttd.panda-water.cn';
export const DEFAULT_MQTT_PATH = '/mqtt';
export const DEFAULT_KEEPLIVE = 60;
export const DEFAULT_TIMEOUT = 50;
export const DEFAULT_PARSE_LEVEL = '1.0';
This diff is collapsed.
/* eslint-disable */
class Message {
constructor({
id,
infoContent,
infoLevel,
time,
infoType,
dateTime,
webConfig,
webPath,
messType,
} = message) {
this.id = id;
this.infoContent = infoContent;
this.infoLevel = infoLevel;
this.time = time;
this.infoType = infoType; // 方案类型 - 工单 报警 公告 定时推送
this.dateTime = dateTime;
this.webConfig = webConfig;
this.webPath = webPath;
this.messType = messType; // 方案名称 - 大类型下细类型
}
}
function createMessage(message) {
return new Message(message);
}
export default createMessage;
......@@ -3,119 +3,115 @@ import { List, Tooltip, Select, Switch } from 'antd';
import defaultSettings from '../../../config/defaultSetting';
import { getFormatMessage } from './index';
export const renderLayoutSettingItem = (item) => {
const action = React.cloneElement(item.action, {
disabled: item.disabled
});
return (
<Tooltip title={item.disabled ? item.disabledReason : ''} placement="left">
<List.Item actions={[action]}>
<span style={{ opacity: item.disabled ? 0.5 : 1 }}>{item.title}</span>
</List.Item>
</Tooltip>
)
export const renderLayoutSettingItem = item => {
const action = React.cloneElement(item.action, {
disabled: item.disabled,
});
return (
<Tooltip title={item.disabled ? item.disabledReason : ''} placement="left">
<List.Item actions={[action]}>
<span style={{ opacity: item.disabled ? 0.5 : 1 }}>{item.title}</span>
</List.Item>
</Tooltip>
);
};
const LayoutSetting = ({ settings = {}, changeSetting }) => {
const formatMessage = getFormatMessage();
const { contentWidth, splitMenus, fixedHeader, layout, fixSiderbar } =
settings || defaultSettings;
return (
<List
split={false}
dataSource={[
{
title: formatMessage({
id: 'app.setting.content-width',
defaultMessage: 'Content Width',
}),
action: (
<Select
value={contentWidth || 'Fixed'}
size="small"
className="content-width"
onSelect={(value) => {
changeSetting('contentWidth', value);
}}
style={{ width: 80 }}
>
{layout === 'side' ? null : (
<Select.Option value="Fixed">
{formatMessage({
id: 'app.setting.content-width.fixed',
defaultMessage: 'Fixed',
})}
</Select.Option>
)}
<Select.Option value="Fluid">
const formatMessage = getFormatMessage();
const { contentWidth, splitMenus, fixedHeader, layout, fixSiderbar } =
settings || defaultSettings;
return (
<List
split={false}
dataSource={[
{
title: formatMessage({
id: 'app.setting.content-width',
defaultMessage: 'Content Width',
}),
action: (
<Select
value={contentWidth || 'Fixed'}
size="small"
className="content-width"
onSelect={value => {
changeSetting('contentWidth', value);
}}
style={{ width: 80 }}
>
{layout === 'side' ? null : (
<Select.Option value="Fixed">
{formatMessage({
id: 'app.setting.content-width.fluid',
defaultMessage: 'Fluid',
id: 'app.setting.content-width.fixed',
defaultMessage: 'Fixed',
})}
</Select.Option>
</Select>
),
},
{
title: formatMessage({
id: 'app.setting.fixedheader',
defaultMessage: 'Fixed Header',
}),
action: (
<Switch
size="small"
disabled
className="fixed-header"
checked={!!fixedHeader}
onChange={(checked) => {
changeSetting('fixedHeader', checked);
}}
/>
),
},
{
title: formatMessage({
id: 'app.setting.fixedsidebar',
defaultMessage: 'Fixed Sidebar',
}),
disabled: layout === 'top',
disabledReason: formatMessage({
id: 'app.setting.fixedsidebar.hint',
defaultMessage: 'Works on Side Menu Layout',
}),
action: (
<Switch
size="small"
disabled
className="fix-siderbar"
checked={!!fixSiderbar}
onChange={(checked) => changeSetting('fixSiderbar', checked)}
/>
),
},
{
title: formatMessage({ id: 'app.setting.splitMenus' }),
disabled: layout !== 'mix',
action: (
<Switch
size="small"
checked={!!splitMenus}
className="split-menus"
onChange={(checked) => {
changeSetting('splitMenus', checked);
}}
/>
),
},
]}
renderItem={renderLayoutSettingItem}
/>
);
};
export default LayoutSetting;
\ No newline at end of file
)}
<Select.Option value="Fluid">
{formatMessage({
id: 'app.setting.content-width.fluid',
defaultMessage: 'Fluid',
})}
</Select.Option>
</Select>
),
},
{
title: formatMessage({
id: 'app.setting.fixedheader',
defaultMessage: 'Fixed Header',
}),
action: (
<Switch
size="small"
disabled
className="fixed-header"
checked={!!fixedHeader}
onChange={checked => {
changeSetting('fixedHeader', checked);
}}
/>
),
},
{
title: formatMessage({
id: 'app.setting.fixedsidebar',
defaultMessage: 'Fixed Sidebar',
}),
disabled: layout === 'top',
disabledReason: formatMessage({
id: 'app.setting.fixedsidebar.hint',
defaultMessage: 'Works on Side Menu Layout',
}),
action: (
<Switch
size="small"
disabled
className="fix-siderbar"
checked={!!fixSiderbar}
onChange={checked => changeSetting('fixSiderbar', checked)}
/>
),
},
{
title: formatMessage({ id: 'app.setting.splitMenus' }),
disabled: layout !== 'mix',
action: (
<Switch
size="small"
checked={!!splitMenus}
className="split-menus"
onChange={checked => {
changeSetting('splitMenus', checked);
}}
/>
),
},
]}
renderItem={renderLayoutSettingItem}
/>
);
};
export default LayoutSetting;
......@@ -35,5 +35,5 @@ export const REQUEST_METHOD_PUT = 'put';
export const REQUEST_METHOD_DELETE = 'delete';
export const WEB_GIS_TYPE = {
ARCGIS: 'ArcgisMap',
AMAP: 'AMap'
}
AMAP: 'AMap',
};
......@@ -35,7 +35,7 @@ import KeepAlive from 'react-activation';
import AMapLoader from '@amap/amap-jsapi-loader';
import RightContent from '@/components/GlobalHeader/ExtendRightContent';
// import Panel from '@/components/SliderPanel/MinPanel';
import { MinPanel as Panel } from '@wisdom-utils/components'
import { MinPanel as Panel } from '@wisdom-utils/components';
import { actionCreators } from '@/containers/App/store';
import { ArcgisMap, AMap, CesiumMap } from '../pages/map';
import { WEB_GIS_TYPE } from '../constants';
......
......@@ -19,7 +19,7 @@ import {
DEFAULT_TCP_IP,
DEFAULT_TCP_PORT,
DEFAULT_PARSE_LEVEL,
} from '@/components/Notifier/constants';
} from '@wisdom-utils/components/lib/AppLayout/notifier/constants';
// eslint-disable-next-line no-undef
const Logger = logger('login');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment