/* eslint-disable no-undef,import/first */ import React from 'react'; import { routerRedux } from 'dva/router'; import * as config from '../utils/config'; import * as utils from '../utils/utils'; import * as services from '../services/services'; import { message, notification, Modal } from 'antd'; import { Toast } from 'antd-mobile'; import * as commonFunc from '../components/Common/commonFunc';/* 通用单据方法 */ if (location.pathname === '/' || location.pathname === '/login') { // localStorage.clear(); } const { confirm } = Modal; export default { namespace: 'app', state: { token: JSON.parse(localStorage.getItem(`${config.prefix}token`)) || {}, rxtx: utils.convertStrToObj(localStorage.getItem(`${config.prefix}rxtx`)), // 获取串口配置 userinfo: JSON.parse(localStorage.getItem(`${config.prefix}userinfo`)) || {}, commonConst: JSON.parse(localStorage.getItem(`${config.prefix}commonConst`)) || [], systemData: JSON.parse(localStorage.getItem(`${config.prefix}systemData`)) || {}, dateFormat: JSON.parse(localStorage.getItem(`${config.prefix}dateFormat`)) || '', panes: JSON.parse(localStorage.getItem(`${config.prefix}panes`)) || [ { paneType: 'home', title: '主页', route: '/indexPage', key: '1', formId: '11811781131121915101184660940', }, ], ppopupPane: {}, secondppopupPane: {}, currentPane: JSON.parse(localStorage.getItem(`${config.prefix}currentPane`)) || { paneType: 'home', title: '主页', route: '/indexPage', key: '1', formId: '11811781131121915101184660940', }, decimals: JSON.parse(localStorage.getItem(`${config.prefix}decimals`)) || '', comParameter: [], /* 常用操作 */ modelCenter: {}, /* KPI工作中心 */ webSocket: null, dataCode: null, sMachineId: localStorage.getItem(`${config.prefix}sMachineId`) || '', // OEE登录存储设备,班组sid sMachineNameStr sTeamNameSId: JSON.parse(localStorage.getItem(`${config.prefix}sTeamNameSId`)) || '', // 保存oee班组id sMachineNameSId: JSON.parse(localStorage.getItem(`${config.prefix}sMachineNameSId`)) || '', // 保存oee机台id sMachineNameStr: JSON.parse(localStorage.getItem(`${config.prefix}sMachineNameStr`)) || '', // 保存oee机台name iPlcNo: localStorage.getItem(`${config.prefix}iPlcNo`) || '', // 保存oeeiPlcNo // 判断页面是否编辑 diffMap: new Map(), managementData: JSON.parse(localStorage.getItem(`${config.prefix}managementData`)) || '', fileData: JSON.parse(localStorage.getItem(`${config.prefix}fileData`)) || '', footer: utils.isJSON(localStorage.getItem(`${config.prefix}footer`)) ? JSON.parse(localStorage.getItem(`${config.prefix}footer`)) : [], logoImageInfo: JSON.parse(localStorage.getItem(`${config.prefix}logoImageInfo`)) || [], auxiliaryQty: utils.isJSON(localStorage.getItem(`${config.prefix}auxiliaryQty`)) ? JSON.parse(localStorage.getItem(`${config.prefix}auxiliaryQty`)) : [], }, reducers: { saveToken(state, { payload: token }) { const currentPane = { paneType: 'home', title: '主页', route: '/indexPage', key: '1', formId: '11811781131121915101184660940', }; const panes = [ { paneType: 'home', title: '主页', route: '/indexPage', key: '1', formId: '11811781131121915101184660940', }, ]; localStorage.setItem(`${config.prefix}token`, JSON.stringify(token)); localStorage.setItem(`${config.prefix}currentPane`, JSON.stringify(currentPane)); localStorage.setItem(`${config.prefix}panes`, JSON.stringify(panes)); const addState = {}; addState.currentPane = currentPane; addState.panes = panes; addState.unRead = 0; addState.enabled = false; return { ...state, token, ...addState }; }, saveCommonConst(state, { payload: commonConst }) { localStorage.setItem(`${config.prefix}commonConst`, JSON.stringify(commonConst)); return { ...state, commonConst }; }, saveUserinfo(state, { payload: userinfo }) { if (state.userinfo.sId !== userinfo.sId) { utils.clearStoreDropDownData(); } localStorage.setItem(`${config.prefix}userinfo`, JSON.stringify(userinfo)); return { ...state, userinfo }; }, saveSystemData(state, { payload: systemData }) { localStorage.setItem(`${config.prefix}systemData`, JSON.stringify(systemData)); return { ...state, systemData }; }, saveDecimals(state, { payload: decimals }) { localStorage.setItem(`${config.prefix}decimals`, JSON.stringify(decimals)); return { ...state, decimals }; }, saveDateFormat(state, { payload: dateFormat }) { localStorage.setItem(`${config.prefix}dateFormat`, JSON.stringify(dateFormat)); return { ...state, dateFormat }; }, savePanes(state, { payload: { panes } }) { localStorage.setItem(`${config.prefix}panes`, JSON.stringify(panes)); return { ...state, panes }; }, saveppopupPane(state, { payload: { ppopupPane } }) { return { ...state, ppopupPane }; }, saveSecondPpopupPane(state, { payload: { secondppopupPane } }) { return { ...state, secondppopupPane }; }, setCurrentPane(state, { payload: { currentPane } }) { localStorage.setItem(`${config.prefix}currentPane`, JSON.stringify(currentPane)); return { ...state, currentPane }; }, /* 当前页和页数一起添加 */ savePanesAndCurrentPane(state, { payload: { panes, currentPane } }) { localStorage.setItem(`${config.prefix}panes`, JSON.stringify(panes)); localStorage.setItem(`${config.prefix}currentPane`, JSON.stringify(currentPane)); return { ...state, panes, currentPane }; }, saveComParameter(state, { payload: { comParameter } }) { return { ...state, comParameter }; }, saveRxtx(state, { payload: rxtx }) { localStorage.setItem(`${config.prefix}rxtx`, JSON.stringify(rxtx)); return { ...state, rxtx }; }, saveModelCenter(state, { payload: { modelCenter, dataCode } }) { return { ...state, modelCenter, dataCode }; }, saveWebSocket(state, { payload: { webSocket } }) { return { ...state, webSocket }; }, saveMsgCount(state, { payload: { msgCount } }) { const addState = {}; if (utils.isNotEmptyObject(msgCount)) { addState.unRead = msgCount; } addState.unReadSid = utils.createSid(); return { ...state, ...addState }; }, saveKpiData(state, { payload: { kpiData } }) { return { ...state, kpiData }; }, saveWorkMsg(state, { payload: { workMsg } }) { return { ...state, workMsg }; }, saveMachineId(state, { payload: { sMachineId } }) { localStorage.setItem(`${config.prefix}sMachineId`, sMachineId); return { ...state, sMachineId }; }, saveTeamNameSId(state, { payload: { sTeamNameSId, sTeamNameSName } }) { localStorage.setItem(`${config.prefix}sTeamNameSId`, JSON.stringify(sTeamNameSId)); localStorage.setItem(`${config.prefix}sTeamNameSName`, JSON.stringify(sTeamNameSName)); return { ...state, sTeamNameSId, sTeamNameSName }; }, saveMachineNameSId(state, { payload: sMachineNameSId, sMachineNameStr }) { localStorage.setItem(`${config.prefix}sMachineNameSId`, JSON.stringify(sMachineNameSId)); localStorage.setItem(`${config.prefix}sMachineNameStr`, JSON.stringify(sMachineNameStr)); return { ...state, sMachineNameSId, sMachineNameStr }; }, saveIPlcNo(state, { payload: iPlcNo }) { localStorage.setItem(`${config.prefix}iPlcNo`, iPlcNo); return { ...state, iPlcNo }; }, saveDiffMap(state, { payload }) { return { ...state, diffMap: state.diffMap.set(payload.sTabId, payload.changed) }; }, saveManagementData(state, { payload: managementData }) { localStorage.setItem(`${config.prefix}managementData`, JSON.stringify(managementData)); return { ...state, managementData }; }, saveFileData(state, { payload: fileData }) { localStorage.setItem(`${config.prefix}fileData`, JSON.stringify(fileData)); return { ...state, fileData }; }, saveFooter(state, { payload: footer }) { localStorage.setItem(`${config.prefix}footer`, JSON.stringify(footer)); return { ...state, footer }; }, saveLogoImageInfo(state, { payload: logoImageInfo }) { localStorage.setItem(`${config.prefix}logoImageInfo`, JSON.stringify(logoImageInfo)); return { ...state, logoImageInfo }; }, saveAuxiliaryQty(state, { payload: auxiliaryQty }) { localStorage.setItem(`${config.prefix}auxiliaryQty`, JSON.stringify(auxiliaryQty)); return { ...state, auxiliaryQty }; }, saveIsInitPassword(state, { payload: isInitPassword }) { return { ...state, isInitPassword }; }, }, effects: { // 修改页面编辑状态; *changeDiffMap({ payload }, { put }) { // payload = { sTabId: '', changed: boolean } yield put({ type: 'saveDiffMap', payload, }); }, /** 修改页签 */ *changePaneData({ payload }, { put, select }) { /* 待用数据赋值 */ const { parentId, /* 父页面编号 */ showRender, /* 主表渲染对象 */ showSlaveRender, /* 从表渲染对象 */ editTableRender, /* 从表渲染控制 */ isRender, /* 是否从高阶渲染 */ isRenderPart, /* 是否进行部分渲染 */ } = payload; /* 参数接收 */ /* 过滤出需要change的pane */ const panes = yield select(state => state.app.panes); const index = panes.findIndex(item => item.key === parentId); /* 父页签存在则进行变更,否则不需要改变什么 */ if (index >= 0) { /* 页签数据变更 */ const pane = panes[index]; pane.showRender = showRender; pane.showSlaveRender = showSlaveRender; pane.editTableRender = editTableRender; pane.isRender = isRender; pane.isRenderPart = isRenderPart; /* 保存页签 */ yield put({ type: 'savePanes', payload: { panes, }, }); } }, /** 添加页签 */ *addNewPane({ payload }, { put, select }) { /* 先获取所有的页签 */ const panes = yield select(state => state.app.panes); const app = yield select(state => state.app); const currentPane = yield select(state => state.app.currentPane); /* 判断页签存储个数是否超过容量 */ if (utils.isNotEmptyArr(panes) && panes.length === config.maxTabSize) { try { throw new Error(commonFunc.showMessage(app.commonConst, 'TabsNumOverLimit'));/* Tab数量已超过限制 */ } catch (e) { console.log('error', e.message); } } /* 获取需要新增的页签 */ const { pane } = payload; pane.parentPaneKey = currentPane.key;/* 增加来源页签key */ /* 判断是否添加页签的条件 */ const index = panes.findIndex(temp => temp.key === pane.key); /* 满足添加条件就添加页签 */ if (index < 0) { panes.push(pane); yield put({ type: 'savePanesAndCurrentPane', payload: { panes, currentPane: pane, }, }); yield put(routerRedux.push(pane.route)); } }, *addPane({ payload }, { put, select }) { const panes = yield select(state => state.app.panes); const app = yield select(state => state.app); if (panes.length === config.maxTabSize) { try { throw new Error(commonFunc.showMessage(app.commonConst, 'TabsNumOverLimit'));/* Tab数量已超过限制 */ } catch (e) { console.log('error', e.message); } } const { pane } = payload; yield put({ type: 'saveCurrentPane', payload: { currentPane: pane } }); const tempPanes = panes.filter(temp => temp.key === pane.key); if (tempPanes.length === 0) { panes.push(pane); } yield put({ type: 'savePanes', payload: { panes } }); }, *addppopupPane({ payload }, { put }) { const { pane } = payload; yield put({ type: 'saveppopupPane', payload: { ppopupPane: pane } }); }, *changePpopupPane({ payload }, { put, select }) { const ppopupPane = yield select(state => state.app.ppopupPane); const { resultValue } = payload; yield put({ type: 'saveppopupPane', payload: { ppopupPane: { ...ppopupPane, resultValue } } }); }, *removeModalPane({ payload }, { put }) { const panes = payload.changePanes; yield put({ type: 'saveppopupPane', payload: { panes } }); }, *addSecondPpopupPane({ payload }, { put }) { const { pane } = payload; yield put({ type: 'saveSecondPpopupPane', payload: { secondppopupPane: pane } }); }, *changeSecondPpopupPane({ payload }, { put, select }) { const secondppopupPane = yield select(state => state.app.secondppopupPane); const { resultValue } = payload; yield put({ type: 'saveSecondPpopupPane', payload: { secondppopupPane: { ...secondppopupPane, resultValue } } }); }, *removeSecondModalPane({ payload }, { put }) { const panes = payload.changePanes; yield put({ type: 'saveSecondPpopupPane', payload: { panes } }); }, *removePane({ payload }, { put }) { const panes = payload.changePanes; const { currentPane } = payload; yield put({ type: 'savePanes', payload: { panes } }); if (panes.length > 0) { yield put({ type: 'saveCurrentPane', payload: { currentPane } }); } }, *saveCurrentPane({ payload }, { put }) { const { currentPane } = payload; yield put({ type: 'setCurrentPane', payload: { currentPane } }); const routeLine = currentPane.route ? currentPane.route : '/indexPage'; yield put(routerRedux.push(routeLine)); }, *throwError({ payload }, { put, select }) { const { code, msg, fn } = payload; const ERROR_MSG_DURATION = 5;/* 3秒 */ if (code === -2) { const webSocket = yield select(state => state.app.webSocket); commonFunc.onWebSocketClose(webSocket, false, null); yield put({ type: 'saveWebSocket', payload: { webSocket: null } }); yield put({ type: 'saveToken', payload: {} }); if (location.pathname.toLowerCase() === '/loginoee') { yield put(routerRedux.push('/loginOee')); } else { yield put(routerRedux.push('/login')); } message.destroy(); message.error(msg, ERROR_MSG_DURATION); } else { message.destroy(); if (code === -7 && !location.pathname.toLowerCase().includes('oee') && !location.pathname.toLowerCase().includes('mobile')) { if (typeof fn === 'function') { confirm({ title: '温馨提示', content:
{msg}
, onOk() { fn(); }, onCancel() { }, okText: '确认', cancelText: '取消', }); } return; } if (code === -1 && !location.pathname.toLowerCase().includes('oee') && !location.pathname.toLowerCase().includes('mobile')) { confirm({ title: '温馨提示', content:{msg}
, okText: '确认', cancelText: '取消', }); return; } message.error(msg, ERROR_MSG_DURATION); } }, *throwErrorMobile({ payload }, { put, select }) { const { code, msg } = payload; const ERROR_MSG_DURATION = 5;/* 3 秒 */ if (code === -2) { const webSocket = yield select(state => state.app.webSocket); commonFunc.onWebSocketClose(webSocket, false, null); yield put({ type: 'saveWebSocket', payload: { webSocket: null } }); yield put({ type: 'saveToken', payload: {} }); yield put(routerRedux.push('/loginMobile')); message.destroy(); message.error(msg, ERROR_MSG_DURATION); } else { message.destroy(); message.error(msg, ERROR_MSG_DURATION); } }, *throwErrorOee({ payload }, { put, select }) { const { code, msg } = payload; const ERROR_MSG_DURATION = 5;/* 3 秒 */ if (code === -2) { const webSocket = yield select(state => state.app.webSocket); commonFunc.onWebSocketClose(webSocket, false, null); yield put({ type: 'saveWebSocket', payload: { webSocket: null } }); yield put({ type: 'saveToken', payload: {} }); yield put(routerRedux.push('/loginOee')); message.destroy(); message.error(msg, ERROR_MSG_DURATION); } else { message.destroy(); message.error(msg, ERROR_MSG_DURATION); } }, *loginOut({ payload }, { call, put, select }) { const { url, sId, loginOutType } = payload; const token = yield select(state => state.app.token); const webSocket = yield select(state => state.app.webSocket); const { data } = yield call(services.getService, token, url); if (data.code === 1) { commonFunc.sendWebSocketMessage(webSocket, 'loginOut', 'noAction', sId, null, sId, sId, null); commonFunc.onWebSocketClose(webSocket, false, null); yield put({ type: 'saveWebSocket', payload: { webSocket: null } }); yield put({ type: 'saveToken', payload: {} }); if (loginOutType === 'loginOut') { yield put(routerRedux.push('/login')); } else if (loginOutType === 'loginMobileOut') { yield put(routerRedux.push('/loginMobile')); } else if (loginOutType === 'loginOeeOut') { yield put(routerRedux.push('/loginOee')); } } else if (loginOutType === 'loginOut') { yield put({ type: 'throwError', payload: data }); } else if (loginOutType === 'loginMobileOut') { yield put({ type: 'throwErrorMobile', payload: data }); } else if (loginOutType === 'loginOeeOut') { yield put({ type: 'throwErrorOee', payload: data }); } }, *editUser({ payload }, { call, put, select }) { const { url, value } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.postValueService, token, value, url); if (data.code === 1) { message.success(data.msg); const userinfo = yield select(state => state.app.userinfo); userinfo.sUserName = value.sUserName; yield put({ type: 'saveUserinfo', payload: userinfo }); } else { yield put({ type: 'throwError', payload: data }); } }, *editPwd({ payload }, { call, put, select }) { const { url, value, editPwdType } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.postValueService, token, value, url); if (editPwdType === 'mobile') { if (data.code === 1) { Toast.success(data.msg, 1); yield put(routerRedux.push('loginMobile')); } else { Toast.fail(data.msg, 1); // yield put({ type: 'throwError', payload: data }); } } else if (editPwdType === 'window') { if (data.code === 1) { message.success(data.msg); yield put(routerRedux.push('/login')); } else { yield put({ type: 'throwError', payload: data }); } } else if (editPwdType === 'oee') { if (data.code === 1) { message.success(data.msg); yield put(routerRedux.push('/loginOee')); } else { yield put({ type: 'throwError', payload: data }); } } }, *resetPwd({ payload }, { call, put, select }) { const { url, value } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.postValueService, token, value, url); if (data.code === 1) { message.success(data.msg); yield put(routerRedux.push('/login')); } else { yield put({ type: 'throwError', payload: data }); } }, *getAddParameter({ payload }, { call, put, select }) { const { url, value } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.postValueService, token, value, url); if (data.code === 1) { const newData = data.dataset.rows[0]; document.getElementById(newData.sFormId).classList.add('actionSelect__selected'); const comParameter = yield select(state => state.app.comParameter); comParameter.push(newData); yield put({ type: 'saveComParameter', payload: { comParameter } }); } else { yield put({ type: 'throwError', payload: data }); } }, *getDelParameter({ payload }, { call, put, select }) { const { url, value } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.postValueService, token, value, url); if (data.code === 1) { const delData = data.dataset.rows[0]; if (document.getElementById(delData.sFormId) !== null) { document.getElementById(delData.sFormId).classList.remove('actionSelect__selected'); } else { const urls = `${config.server_host}business/getBuMenu?sModelsId=100`; yield put({ type: 'menuPanel/getMenuPanel', payload: { url: urls } }); } const comParameter = yield select(state => state.app.comParameter); const index = comParameter.findIndex(item => item.sFormId === delData.sFormId); comParameter.splice(index, 1); yield put({ type: 'saveComParameter', payload: { comParameter } }); } else { yield put({ type: 'throwError', payload: data }); } }, *getComParameter({ payload }, { call, put, select }) { const { url } = payload; const token = yield select(state => state.app.token); const { data } = yield call(services.getService, token, url); if (data.code === 1) { const comParameter = data.dataset.rows; yield put({ type: 'saveComParameter', payload: { comParameter } }); } else { yield put({ type: 'throwError', payload: data }); } }, *getModelCenter({ payload }, { call, put, select }) { const { value, url, dispatch } = payload; const token = yield select(state => state.app.token); const webSocket = yield select(state => state.app.webSocket); let dataCode = 0; const { data } = yield call(services.postValueService, token, value, url); if (utils.isEmpty(webSocket)) { const reStart = true; yield put({ type: 'createWebSocket', payload: { reStart, dispatch } }); } if (data.code === 1) { const modelCenter = data.dataset.rows[0]; if (url.indexOf('getModelCenterCalculation') > -1) { dataCode = 1; } yield put({ type: 'saveModelCenter', payload: { modelCenter, dataCode } }); } else { yield put({ type: 'throwError', payload: data }); } }, *clearModelCenter(content, { put }) { yield put({ type: 'saveModelCenter', payload: { modelCenter: {}, dataCode: null } }); }, /** 返回新页签 */ *backPane({ payload }, { put }) { const { panes, currentPane } = payload; yield put({ type: 'savePanes', payload: { panes } }); yield put({ type: 'saveCurrentPane', payload: { currentPane } }); }, /** 返回新页签 */ *createWebSocket({ payload }, { put, select }) { const { reStart, dispatch } = payload; const userinfo = yield select(state => state.app.userinfo); const existingWs = yield select(state => state.app.webSocket); if (existingWs) { console.log('333', existingWs.readyState, WebSocket.OPEN, WebSocket.CONNECTING); if (existingWs.readyState === WebSocket.OPEN) { console.log('已有活跃WebSocket连接,跳过创建新连接'); return; } if (existingWs.readyState === WebSocket.CONNECTING) { console.log('WebSocket正在连接中,跳过创建新连接'); return; } } let url = `${config.ws_host}websocket/${userinfo.sId}`; if (userinfo.sUserLoginType) { url = `${config.ws_host}websocket/${userinfo.sId}?sLoginType=${userinfo.sUserLoginType}`; } if (reStart) { // const webSocket = yield select(state => state.app.webSocket); // if (webSocket === null) { // return null; // } url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true`; if (userinfo.sUserLoginType) { url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&sLoginType=${userinfo.sUserLoginType}`; } } // const reset = (ws, config1) => { // clearTimeout(config1.timerServer); // clearTimeout(config1.serverTimer); // start(ws, config1); // }; // const start = (ws, config1) => { // config1.timerServer = setTimeout(() => { // const message = { sendFrom: userinfo.sId, connectTest: 'test' }; // param 存放其它参数 keyName 需要放入Redis的数据key,keyValue 需要放入Redis的数据key 的值 // ws.send(JSON.stringify(message)); // }, config1.timeoutServer); // }; // 心跳包相关变量 let heartbeatInterval; let lastHeartbeatTime = Date.now(); const HEARTBEAT_INTERVAL = 30000; // 30秒发送一次心跳 const HEARTBEAT_TIMEOUT = 60000; // 60秒无响应则断开 const resetHeartbeat = () => { lastHeartbeatTime = Date.now(); }; const sendHeartbeat = (ws) => { if (ws.readyState === WebSocket.OPEN) { const message = { sendFrom: userinfo.sId, connectTest: 'test', // 心跳标识 timestamp: Date.now(), }; ws.send(JSON.stringify(message)); } }; const ws = new WebSocket(url); ws.onopen = function (e) { console.log('WebSocket连接成功', e); // 启动心跳定时器 heartbeatInterval = setInterval(() => { sendHeartbeat(ws); // 检查是否超时 if (Date.now() - lastHeartbeatTime > HEARTBEAT_TIMEOUT) { console.log('心跳超时,主动断开连接'); ws.close(); } }, HEARTBEAT_INTERVAL); }; // 全局通用的自定义onmessage的方法 ws.homeAction = (msg) => { const rtmsg = JSON.parse(msg.data); if (rtmsg.action === 'showImg' && location.pathname.indexOf('/indexOee') < 0) { const msgData = JSON.parse(msg.data); const msgStr = JSON.stringify(msgData.msg); const msgObj = utils.isJSON(msgStr) ? JSON.parse(msgStr) : {}; const msgPopupData = utils.isNotEmptyArr(msgObj.popup) ? msgObj.popup : []; const msgHeadData = utils.isNotEmptyObject(msgObj.data) ? msgObj.data : []; if (utils.isNotEmptyObject(msgHeadData)) { if (utils.isNotEmptyArr(msgPopupData)) { if (location.pathname.indexOf('/indexMobile') < 0) { msgPopupData.forEach((child) => { // const sFormId = utils.isEmptyObject(child.sFormId) ? '15669750700007338351055957774000' : child.sFormId; // eslint-disable-next-line no-unused-vars // const pane = { // title: '消息列表', route: '/indexPage/commonList', formId: sFormId, key: utils.createSid(), sModelsType: 'commonList/msg', // }; // eslint-disable-next-line prefer-destructuring const pane = child.pane; notification.info({ message: child.sTypeName, description: child.sContent, className: 'customNotification', // icon: