index.js 24.5 KB
Newer Older
邓晓峰's avatar
邓晓峰 committed
1
import 'kit_logger';
叶飞's avatar
叶飞 committed
2

邓晓峰's avatar
邓晓峰 committed
3 4 5
import _ from 'lodash';
import MqttClient from 'mqtt-client';

邓晓峰's avatar
邓晓峰 committed
6
import { noticeService } from '../../api';
7
import { postInformationStatus } from '../../api/service/notification';
邓晓峰's avatar
邓晓峰 committed
8
import { isJSON } from '../../utils/utils';
邓晓峰's avatar
邓晓峰 committed
9 10 11 12 13 14 15 16 17 18 19 20 21
import {
  DEFAULT_KEEPLIVE,
  DEFAULT_MQTT_PATH,
  DEFAULT_PARSE_LEVEL,
  DEFAULT_TCP_IP,
  DEFAULT_TCP_PORT,
  DEFAULT_TIMEOUT,
  ERR_OK,
  MESSAGE_TEXT_TYPE,
  MESSAGE_TYPE,
  NEW_MESSAGE,
  PASSWORD,
  PLATFORM_LEVEL,
邓晓峰's avatar
邓晓峰 committed
22 23
  REQUEST_SERVICE,
  SYS_LEVEL,
邓晓峰's avatar
邓晓峰 committed
24 25 26 27
  USERNAME,
  VIDEO_LEVEL,
} from './constants';
import createMessage from './message';
邓晓峰's avatar
邓晓峰 committed
28

邓晓峰's avatar
邓晓峰 committed
29 30 31
/* eslint-disable */
// eslint-disable-next-line no-undef
const Logger = logger('mqtt');
叶飞's avatar
叶飞 committed
32
class Notifier {
33
  constructor(userInfo, renderVideo, renderPlatform, renderSysPlatform, props) {
叶飞's avatar
叶飞 committed
34
    this.userInfo = userInfo;
叶飞's avatar
叶飞 committed
35 36 37
    this.messageCache = {
      totalCount: 0,
      messages: [],
邓晓峰's avatar
邓晓峰 committed
38 39
    };
    // 当前消息缓存
邓晓峰's avatar
邓晓峰 committed
40
    this._subscribers = {}; // 订阅器缓存
叶飞's avatar
叶飞 committed
41 42 43
    this._siteConfig = {
      site_code: this.userInfo.site,
      TcpIP: '',
邓晓峰's avatar
邓晓峰 committed
44
      TcpPort: DEFAULT_TCP_PORT,
叶飞's avatar
叶飞 committed
45 46 47
      TimeOut: '',
      KeepAlive: '',
      IsSSL: true,
邓晓峰's avatar
邓晓峰 committed
48
      mqtt_path: DEFAULT_MQTT_PATH,
邓晓峰's avatar
邓晓峰 committed
49 50 51
      mqtt_mess: {},
      nginxStart: false

叶飞's avatar
叶飞 committed
52 53 54 55 56
    };
    this.MQTTCount = 0;
    this.MQTTClient = null;
    this.MQTTOptions = {};
    this.IsNeedReconnect = true;
叶飞's avatar
叶飞 committed
57 58
    this.currentPageIndex = 1;
    this.currentPageSize = 10;
叶飞's avatar
叶飞 committed
59

叶飞's avatar
叶飞 committed
60 61 62 63 64 65 66
    this.start = this.start.bind(this);
    this.stop = this.stop.bind(this);
    this.subscribe = this.subscribe.bind(this);
    this.unsubscribe = this.unsubscribe.bind(this);
    this.confirmRead = this.confirmRead.bind(this);
    this.loadMore = this.loadMore.bind(this);
    this.hasMore = this.hasMore.bind(this);
邓晓峰's avatar
邓晓峰 committed
67 68
    this.renderVideo = renderVideo;
    this.renderPlatform = renderPlatform;
69
    this.renderSysPlatform = renderSysPlatform;
邓晓峰's avatar
邓晓峰 committed
70
    this.props = props;
叶飞's avatar
叶飞 committed
71
  }
邓晓峰's avatar
邓晓峰 committed
72

叶飞's avatar
叶飞 committed
73 74
  // 对外接口
  async start() {
叶飞's avatar
叶飞 committed
75
    window.cc = this.messageCache;
邓晓峰's avatar
邓晓峰 committed
76
    this.getMqttSiteCode().then((res) => {
叶飞's avatar
叶飞 committed
77
      this.loadHisMessages(this.currentPageIndex, this.currentPageSize);
叶飞's avatar
叶飞 committed
78 79
      this.connectMQTTServer();
    });
叶飞's avatar
叶飞 committed
80
  }
邓晓峰's avatar
邓晓峰 committed
81

叶飞's avatar
叶飞 committed
82 83 84
  stop() {
    this.disconnectMQTTServer();
  }
邓晓峰's avatar
邓晓峰 committed
85

叶飞's avatar
叶飞 committed
86 87 88 89 90 91
  subscribe(type, handler) {
    if (!(type in this._subscribers)) {
      this._subscribers[type] = [];
    }
    this._subscribers[type].push(handler);
  }
邓晓峰's avatar
邓晓峰 committed
92

叶飞's avatar
叶飞 committed
93 94
  unsubscribe(type, handler) {
    if (!(type in this._subscribers)) {
邓晓峰's avatar
邓晓峰 committed
95
      logger.info('无效事件无法删除');
叶飞's avatar
叶飞 committed
96 97 98 99 100 101
    }
    if (!handler) {
      delete this._subscribers[type];
    } else {
      const idx = this._subscribers[type].findIndex(ele => ele === handler);
      if (idx === -1) {
邓晓峰's avatar
邓晓峰 committed
102
        logger.info('无效事件无法删除');
叶飞's avatar
叶飞 committed
103 104 105 106 107 108 109 110
        return;
      }
      this._subscribers[type].splice(idx, 1);
      if (this._subscribers[type].length === 0) {
        delete this._subscribers[type];
      }
    }
  }
邓晓峰's avatar
邓晓峰 committed
111

叶飞's avatar
叶飞 committed
112
  publish(type, payload) {
邓晓峰's avatar
邓晓峰 committed
113
    if (!(type in this._subscribers) || this._subscribers[type].length === 0) {
叶飞's avatar
叶飞 committed
114
      return;
邓晓峰's avatar
邓晓峰 committed
115
    }
叶飞's avatar
叶飞 committed
116 117 118 119
    this._subscribers[type].forEach(handler => {
      try {
        handler(payload);
      } catch (e) {
邓晓峰's avatar
邓晓峰 committed
120 121
        // eslint-disable-next-line no-undef
        logger.warn(`订阅器委托错误${e.message}`);
叶飞's avatar
叶飞 committed
122 123 124
      }
    });
  }
邓晓峰's avatar
邓晓峰 committed
125

叶飞's avatar
叶飞 committed
126 127 128
  confirmRead(isAll = false, hisIDs = []) {
    if (
      this.messageCache &&
邓晓峰's avatar
邓晓峰 committed
129 130 131
      this.messageCache.totalCount === 0 &&
      this.messageCache.messages.length === 0
    ) {
叶飞's avatar
叶飞 committed
132
      return;
邓晓峰's avatar
邓晓峰 committed
133
    }
叶飞's avatar
叶飞 committed
134
    if (isAll) hisIDs = this.messageCache.messages.map(item => item.id);
邓晓峰's avatar
邓晓峰 committed
135 136
    const self = this;
    // eslint-disable-next-line no-undef
137
    
138
    postInformationStatus({
139
      userID: this.userInfo.OID || window.globalConfig.userInfo.OID,
叶飞's avatar
叶飞 committed
140 141 142 143
      hisID: hisIDs.join(','),
      isAll: isAll ? 1 : '',
    })
      .then(res => {
邓晓峰's avatar
邓晓峰 committed
144 145
        if (res.statusCode !== ERR_OK) {
          Logger.info(res.errMsg);
叶飞's avatar
叶飞 committed
146 147 148
          return;
        }
        if (isAll) {
邓晓峰's avatar
邓晓峰 committed
149 150 151
          self.messageCache.totalCount = 0;
          self.messageCache.messages = [];
          self.currentPageIndex = 1;
叶飞's avatar
叶飞 committed
152 153
        } else {
          hisIDs.forEach(id => {
邓晓峰's avatar
邓晓峰 committed
154
            const index = self.messageCache.messages.findIndex(
邓晓峰's avatar
邓晓峰 committed
155
              item => item.id === id,
叶飞's avatar
叶飞 committed
156
            );
邓晓峰's avatar
邓晓峰 committed
157 158
            if (index > -1) {
              self.messageCache.messages.splice(index, 1);
邓晓峰's avatar
邓晓峰 committed
159
              // eslint-disable-next-line no-plusplus
邓晓峰's avatar
邓晓峰 committed
160
              self.messageCache.totalCount--;
叶飞's avatar
叶飞 committed
161 162 163
            }
          });
        }
邓晓峰's avatar
邓晓峰 committed
164
        self.publish(NEW_MESSAGE, self.messageCache);
叶飞's avatar
叶飞 committed
165 166
      })
      .catch(err => {
邓晓峰's avatar
邓晓峰 committed
167 168
        // eslint-disable-next-line no-undef
        logger.error(`postInformationStatus调用失败${err}`);
叶飞's avatar
叶飞 committed
169 170
      });
  }
邓晓峰's avatar
邓晓峰 committed
171

叶飞's avatar
叶飞 committed
172 173 174 175 176
  hasMore() {
    if (!this.messageCache) return false;
    if (!this.messageCache.totalCount) return false;
    return this.messageCache.totalCount > this.messageCache.messages.length;
  }
邓晓峰's avatar
邓晓峰 committed
177

叶飞's avatar
叶飞 committed
178 179
  loadMore(callback) {
    if (!this.hasMore()) return Promise.resolve([]);
叶飞's avatar
叶飞 committed
180
    this.currentPageIndex += 1;
叶飞's avatar
叶飞 committed
181 182
    return this.loadHisMessages(this.currentPageIndex, this.currentPageSize);
  }
邓晓峰's avatar
邓晓峰 committed
183

叶飞's avatar
叶飞 committed
184 185
  // mqtt
  async connectMQTTServer() {
邓晓峰's avatar
邓晓峰 committed
186 187
    const hostname = this._siteConfig.TcpIP;
    const port = this._siteConfig.TcpPort;
邓晓峰's avatar
邓晓峰 committed
188
    const clientId = `client-${this.generatedId()}`;
邓晓峰's avatar
邓晓峰 committed
189 190 191 192 193 194 195
    const timeout = DEFAULT_TIMEOUT;
    const keepAlive = DEFAULT_KEEPLIVE;
    const cleanSession = true;
    const ssl = this._siteConfig.IsSSL;
    const userName = USERNAME;
    const password = PASSWORD;
    const path = this._siteConfig.mqtt_path;
叶飞's avatar
叶飞 committed
196
    this.MQTTCount = 0;
邓晓峰's avatar
邓晓峰 committed
197
    if (hostname) {
邓晓峰's avatar
邓晓峰 committed
198 199 200 201
      this.MQTTClient = new MqttClient.Client(hostname, port, path, clientId);
      this.MQTTOptions = {
        invocationContext: {
          host: hostname,
邓晓峰's avatar
邓晓峰 committed
202 203 204
          port,
          path,
          clientId,
邓晓峰's avatar
邓晓峰 committed
205
        },
邓晓峰's avatar
邓晓峰 committed
206
        timeout,
邓晓峰's avatar
邓晓峰 committed
207
        keepAliveInterval: keepAlive,
邓晓峰's avatar
邓晓峰 committed
208
        cleanSession,
邓晓峰's avatar
邓晓峰 committed
209
        useSSL: ssl,
邓晓峰's avatar
邓晓峰 committed
210 211
        userName,
        password,
邓晓峰's avatar
邓晓峰 committed
212
        onSuccess: this.onMQTTConnect.bind(this),
邓晓峰's avatar
邓晓峰 committed
213
        onFailure(e) {
邓晓峰's avatar
邓晓峰 committed
214 215 216 217 218 219 220
          console.log(e);
        },
      };
      this.MQTTClient.connect(this.MQTTOptions);
      this.MQTTClient.onConnectionLost = this.onMQTTConnectionLost.bind(this);
      this.MQTTClient.onMessageArrived = this.onMessageArrived.bind(this);
    }
叶飞's avatar
叶飞 committed
221
  }
邓晓峰's avatar
邓晓峰 committed
222

叶飞's avatar
叶飞 committed
223 224 225
  disconnectMQTTServer() {
    if (this.MQTTClient) {
      this.IsNeedReconnect = false;
邓晓峰's avatar
邓晓峰 committed
226
      this.MQTTClient.disconnect();
叶飞's avatar
叶飞 committed
227 228 229
      this.MQTTClient = null;
    }
  }
邓晓峰's avatar
邓晓峰 committed
230

邓晓峰's avatar
邓晓峰 committed
231 232 233 234 235 236 237 238 239 240 241 242
  getSiteCode() {
    return this._siteConfig.site_code;
  }

  getUserInfo() {
    return this.userInfo;
  }

  getSiteConfig() {
    return this._siteConfig;
  }

叶飞's avatar
叶飞 committed
243
  onMQTTConnect() {
邓晓峰's avatar
邓晓峰 committed
244
    const site = this.getSiteCode();
邓晓峰's avatar
邓晓峰 committed
245
    // 信息化主题
邓晓峰's avatar
邓晓峰 committed
246
    this.MQTTClient.subscribe(site + REQUEST_SERVICE.EIMTopic);
邓晓峰's avatar
邓晓峰 committed
247
    // 节水主题
邓晓峰's avatar
邓晓峰 committed
248
    this.MQTTClient.subscribe(site + REQUEST_SERVICE.SaveWaTopic);
邓晓峰's avatar
邓晓峰 committed
249
    // 系统主题
邓晓峰's avatar
邓晓峰 committed
250
    this.MQTTClient.subscribe(site + REQUEST_SERVICE.SystemTopic);
邓晓峰's avatar
邓晓峰 committed
251
    // 工单主题
邓晓峰's avatar
邓晓峰 committed
252
    this.MQTTClient.subscribe(site + REQUEST_SERVICE.WorkerOrderTopic);
邓晓峰's avatar
邓晓峰 committed
253
    // 报警主题
邓晓峰's avatar
邓晓峰 committed
254
    this.MQTTClient.subscribe(site + REQUEST_SERVICE.ScadaTopic);
邓晓峰's avatar
邓晓峰 committed
255
    // 用户主题
邓晓峰's avatar
邓晓峰 committed
256
    this.MQTTClient.subscribe(
邓晓峰's avatar
邓晓峰 committed
257
      `${site}${REQUEST_SERVICE.UserTopic}${this.userInfo.OID}`,
邓晓峰's avatar
邓晓峰 committed
258
    );
叶飞's avatar
叶飞 committed
259
  }
邓晓峰's avatar
邓晓峰 committed
260

叶飞's avatar
叶飞 committed
261
  onMQTTConnectionLost(responseObject) {
邓晓峰's avatar
邓晓峰 committed
262
    const self = this;
叶飞's avatar
叶飞 committed
263
    if (this.IsNeedReconnect) {
邓晓峰's avatar
邓晓峰 committed
264
      this.MQTTClient.connect(self.MQTTOptions);
叶飞's avatar
叶飞 committed
265
      this.MQTTtester = setInterval(function() {
邓晓峰's avatar
邓晓峰 committed
266 267
        if (self.MQTTClient.isConnected) {
          clearInterval(self.MQTTtester);
叶飞's avatar
叶飞 committed
268
        } else {
邓晓峰's avatar
邓晓峰 committed
269
          self.MQTTClient.connect(self.MQTTOptions);
叶飞's avatar
叶飞 committed
270 271 272 273
        }
      }, 1000);
    }
  }
邓晓峰's avatar
邓晓峰 committed
274

叶飞's avatar
叶飞 committed
275
  onMessageArrived(buffer) {
叶飞's avatar
叶飞 committed
276
    try {
邓晓峰's avatar
邓晓峰 committed
277 278 279 280
      const parseMessage = JSON.parse(buffer.payloadString);
      const userInfo = this.getUserInfo();
      const infoType = this.getMessageType(parseMessage.infoType);
      let state = null;
叶飞's avatar
叶飞 committed
281
      if (
邓晓峰's avatar
邓晓峰 committed
282 283
        _.isEmpty(parseMessage.tousers) ||
        userInfo.OID == parseMessage.tousers ||
邓晓峰's avatar
邓晓峰 committed
284 285
        parseMessage.tousers.includes(`${userInfo.OID},`) ||
        parseMessage.tousers.includes(`,${userInfo.OID}`)
叶飞's avatar
叶飞 committed
286
      ) {
邓晓峰's avatar
邓晓峰 committed
287 288 289 290
        if (
          document.visibilityState === 'visible' ||
          document.visibilityState === 'hidden'
        ) {
邓晓峰's avatar
邓晓峰 committed
291 292
          this.renderWindowsInfo(buffer);
        }
邓晓峰's avatar
邓晓峰 committed
293
        let messContent = parseMessage.content;
邓晓峰's avatar
邓晓峰 committed
294

邓晓峰's avatar
邓晓峰 committed
295 296 297
        if(this._siteConfig.MessageLevel && this._siteConfig.MessageLevel === "2.0") {
          messContent = this.messageThrome(infoType, JSON.parse(parseMessage.content))
        }
邓晓峰's avatar
邓晓峰 committed
298 299
        const timeH =
          (new Date() - new Date(parseMessage.createTime)) / 1000 / 60;
邓晓峰's avatar
邓晓峰 committed
300
        const timeMss =
叶飞's avatar
叶飞 committed
301
          Math.abs(timeH) > 1440
邓晓峰's avatar
邓晓峰 committed
302
            ? parseMessage.createTime.split('.')[0]
叶飞's avatar
叶飞 committed
303
            : Math.abs(timeH) > 60
邓晓峰's avatar
邓晓峰 committed
304
            ? `${(timeH / 60).toFixed(0)}小时前`
叶飞's avatar
叶飞 committed
305
            : Math.abs(timeH) > 1
邓晓峰's avatar
邓晓峰 committed
306
            ? `${timeH.toFixed(0)}分钟前`
叶飞's avatar
叶飞 committed
307
            : '刚刚';
邓晓峰's avatar
邓晓峰 committed
308
        const messString = {
邓晓峰's avatar
邓晓峰 committed
309 310
          id: parseMessage.infoId,
          infoContent: parseMessage.content,
邓晓峰's avatar
邓晓峰 committed
311
          infoLevel: parseMessage.level,
叶飞's avatar
叶飞 committed
312
          time: `${timeMss}`,
邓晓峰's avatar
邓晓峰 committed
313
          infoType,
邓晓峰's avatar
邓晓峰 committed
314 315 316 317
          dateTime: parseMessage.createTime,
          webConfig: parseMessage.web_config,
          webPath: parseMessage.web_path,
          messType: parseMessage.MessType,
叶飞's avatar
叶飞 committed
318
        };
邓晓峰's avatar
邓晓峰 committed
319

邓晓峰's avatar
邓晓峰 committed
320 321
        if (parseMessage.tousers === '') {
          messString.messType = '公告';
邓晓峰's avatar
邓晓峰 committed
322
          let content = (_.isObject(messContent) ? messContent.content: messContent).replace(/\\n/g, ',');
邓晓峰's avatar
邓晓峰 committed
323
          content = this.replaceSpeak(content)
邓晓峰's avatar
邓晓峰 committed
324 325 326 327 328
          state = new window.SpeechSynthesisUtterance(
            `您有新的公告:${content
              .substring(0, content.lastIndexOf(','))
              .replace(':', ',')} 时间:${timeMss}`,
          );
邓晓峰's avatar
邓晓峰 committed
329
        } else {
邓晓峰's avatar
邓晓峰 committed
330
          let content = ( _.isObject(messContent) ? messContent.content: messContent).replace(/\\n/g, ',');
邓晓峰's avatar
邓晓峰 committed
331
          content = this.replaceSpeak(content)
邓晓峰's avatar
邓晓峰 committed
332 333 334 335 336
          state = new window.SpeechSynthesisUtterance(
            `您有新的消息:${content
              .substring(0, content.lastIndexOf(','))
              .replace(':', ',')} 时间:${timeMss}`,
          );
邓晓峰's avatar
邓晓峰 committed
337 338 339 340
        }

        if (this.getParseVesion()) {
          messString.infoContent = this.parseMessageToJSON(
叶飞's avatar
叶飞 committed
341 342 343
            infoType,
            messString,
          );
邓晓峰's avatar
邓晓峰 committed
344 345 346 347 348 349
        } else {
          messString.infoContent = JSON.parse(
            JSON.stringify(messString.infoContent || '{}'),
          );
        }
        const message = createMessage(messString);
叶飞's avatar
叶飞 committed
350
        this.messageCache.totalCount += 1;
351 352 353 354 355 356
        if(message.infoLevel === SYS_LEVEL) {
          this.messageCache.messages.unshift(message)
        } else {
          this.messageCache.messages.push(message);
        }

邓晓峰's avatar
邓晓峰 committed
357
        this.publish(NEW_MESSAGE, this.messageCache);
邓晓峰's avatar
邓晓峰 committed
358 359 360 361 362 363
        if (
          messString.infoLevel === PLATFORM_LEVEL &&
          messString.infoType === MESSAGE_TYPE.SCADA_TYPE
        ) {
          this.parseScadaMessage(Object.assign(message, { messContent }));
          this.renderPopPlatform(Object.assign(message, { messContent }));
邓晓峰's avatar
邓晓峰 committed
364
        } else if (messString.infoLevel === VIDEO_LEVEL) {
邓晓峰's avatar
邓晓峰 committed
365 366
          this.renderPopVideo(Object.assign(message, { messContent }));
          state.lang = 'zh';
邓晓峰's avatar
邓晓峰 committed
367 368
          state.rate = 1;
          window.speechSynthesis.speak(state);
邓晓峰's avatar
邓晓峰 committed
369 370
        } else if (message.infoLevel === PLATFORM_LEVEL) {
          console.log(messString);
371 372
        } else if(message.infoLevel === SYS_LEVEL) {
          this.renderSysNoticePlatform(Object.assign(message, { messContent }))
邓晓峰's avatar
邓晓峰 committed
373
        } else {
邓晓峰's avatar
邓晓峰 committed
374
          state.lang = 'zh';
邓晓峰's avatar
邓晓峰 committed
375 376 377
          state.rate = 1;
          window.speechSynthesis.speak(state);
        }
378 379 380



叶飞's avatar
叶飞 committed
381 382
      }
    } catch (e) {
邓晓峰's avatar
邓晓峰 committed
383
      Logger.error(`收到消息处理异常:${e.message}`);
叶飞's avatar
叶飞 committed
384 385 386
    }
  }

邓晓峰's avatar
邓晓峰 committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
  replaceSpeak(msg) {
    msg = msg.replaceAll(" ", "");
    msg = msg.replace(/MPa/ig, "兆帕");
    msg = msg.replace(/m³\/h/ig, "立方米每小时");
    msg = msg.replace(/m³/ig, "立方米");
    msg = msg.replace(/kWh/ig, "千瓦时");
    msg = msg.replace(/kW/ig, "千瓦");
    msg = msg.replace(/min/ig, "分钟");
    msg = msg.replace(/m/ig, "米");
    msg = msg.replace(/A/ig, "安");
    msg = msg.replace(/V/ig, "伏");
    msg = msg.replace(/h/ig, "小时");
    return msg;
  }
  messageThrome(themeName, info) {
    let messageInfo = "";
    switch (themeName) {
      case MESSAGE_TYPE.CASE_TYPE:
      case "工单提醒":
        messageInfo = `【${info.caseType}${info.flowName}\\n${info.nodeName}\\n承办意见:${info.content}`;
        break;
      case MESSAGE_TYPE.SCADA_TYPE:
      case "通用报警":
邓晓峰's avatar
邓晓峰 committed
410
        messageInfo = `${info.title} \\n ${info.content.replace(", ", "\\n")}\\n${info.deviceCode}`;
邓晓峰's avatar
邓晓峰 committed
411 412 413 414 415 416 417 418 419 420 421 422
        break;
      case MESSAGE_TYPE.SYS_TYPE:
      case "系统通知":
        messageInfo = `【${info.noticeType}${info.noticeTitle}\\n${info.noticeContent}`;
        break;
      default:
        messageInfo = info;
        break;
    }
    return messageInfo;
  }

邓晓峰's avatar
邓晓峰 committed
423
  renderWindowsInfo(message) {
邓晓峰's avatar
邓晓峰 committed
424
    const self = this;
邓晓峰's avatar
邓晓峰 committed
425 426
    function notifyMessage(message) {
      const parseMessage = JSON.parse(message.payloadString);
邓晓峰's avatar
邓晓峰 committed
427
      let content = '';
428 429 430 431 432 433 434 435 436 437
      if(message.level !== SYS_LEVEL) {
        if(self.getMessageLevel() === "2.0") {
          if(message.level === "4") {
            const messageContent = JSON.parse(parseMessage.content);
            content += `${messageContent.alarmType} ${messageContent.alarmDevice} ${messageContent.alarmContent} ${messageContent.alarmValue} / ${messageContent.alarmThreshold}`
          }
        } else {
          for (let i = 0; i < parseMessage.content.split('\\n').length; i++) {
            content += `${parseMessage.content.split('\\n')[i]} `;
          }
邓晓峰's avatar
邓晓峰 committed
438
        }
邓晓峰's avatar
邓晓峰 committed
439
      }
邓晓峰's avatar
邓晓峰 committed
440

441

邓晓峰's avatar
邓晓峰 committed
442 443 444
      const messageBody = {
        title: '',
        content,
邓晓峰's avatar
邓晓峰 committed
445 446
      };

邓晓峰's avatar
邓晓峰 committed
447 448
      if (parseMessage.tousers === '') {
        messageBody.title = '新公告:';
邓晓峰's avatar
邓晓峰 committed
449
      } else {
邓晓峰's avatar
邓晓峰 committed
450
        messageBody.title = '新通知:';
邓晓峰's avatar
邓晓峰 committed
451
      }
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
      if(content !== "") {
        if (!('Notification' in window)) {
          message.warn('This browser does not support desktop notification');
        } else if (Notification.permission === 'granted') {
          const notification = new Notification(messageBody.title, {
            body: `${messageBody.content}`,
            icon: 'https://panda-water.com/web4/assets/images/icon/熊猫新1.png',
          });
          notification.onclick = () => {
            notification.close();
          };
        } else if (Notification.permission !== 'denied') {
          Notification.requestPermission(permission => {
            if (permission === 'granted') {
              const notification = new Notification(messageBody.title, {
                body: `${messageBody.content}`,
                icon:
                  'https://panda-water.com/web4/assets/images/icon/熊猫新1.png',
              });
              notification.onclick = () => {
                notification.close();
              };
            }
          });
        }
邓晓峰's avatar
邓晓峰 committed
477
      }
478

叶飞's avatar
叶飞 committed
479
    }
邓晓峰's avatar
邓晓峰 committed
480 481 482 483
    notifyMessage(message);
  }

  renderPopPlatform(message) {
邓晓峰's avatar
邓晓峰 committed
484
    this.renderPlatformElement =
邓晓峰's avatar
邓晓峰 committed
485
      this.renderPlatform && this.renderPlatorm(message);
邓晓峰's avatar
邓晓峰 committed
486 487
  }

488
  renderSysNoticePlatform(message) {
489
    this.renderSysPlatform && this.renderSysPlatform(message)
490 491
  }

邓晓峰's avatar
邓晓峰 committed
492 493 494 495 496 497 498 499 500 501
  renderPopVideo(message) {
    this.renderVideoElement = this.renderVideo && this.renderVideo(message);
  }

  destoryPlatform() {
    this.renderPlatformElement = null;
  }

  destoryVideo() {
    this.renderVideoElement = null;
叶飞's avatar
叶飞 committed
502 503 504
  }

  // 工具类
叶飞's avatar
叶飞 committed
505
  async loadHisMessages(pageIndex, pageSize) {
邓晓峰's avatar
邓晓峰 committed
506
    const self = this;
邓晓峰's avatar
邓晓峰 committed
507
    return noticeService.getInformationInfo({
邓晓峰's avatar
邓晓峰 committed
508
      userID: self.getUserInfo().OID,
叶飞's avatar
叶飞 committed
509 510 511 512
      pageIndex,
      pageSize,
      'request.preventCache': Date.now(),
    }).then(res => {
邓晓峰's avatar
邓晓峰 committed
513
      if (res) {
邓晓峰's avatar
邓晓峰 committed
514
        const result = {
邓晓峰's avatar
邓晓峰 committed
515
          totalCount: res.totalRcdNum,
邓晓峰's avatar
邓晓峰 committed
516
          messages: (Array.isArray(res.getMe) ? res.getMe: []) .map(this.parseHisToMessage.bind(this)),
邓晓峰's avatar
邓晓峰 committed
517 518 519
        };
        self.messageCache.totalCount = result.totalCount;
        (result.messages || []).forEach(message => {
邓晓峰's avatar
邓晓峰 committed
520
          const index = self.messageCache.messages.findIndex(
邓晓峰's avatar
邓晓峰 committed
521
            item => item.id === message.id,
邓晓峰's avatar
邓晓峰 committed
522
          );
邓晓峰's avatar
邓晓峰 committed
523
          index === -1 && self.messageCache.messages.push(message);
叶飞's avatar
叶飞 committed
524
        });
邓晓峰's avatar
邓晓峰 committed
525 526 527 528 529 530 531 532
        if (
          self.messageCache.totalCount > self.messageCache.messages.length &&
          res.getMe.length === 0
        ) {
          // 服务端返回总数还有,但是查不到数据了,前端修正服务端返回的总数
          self.messageCache.totalCount = self.messageCache.messages.length;
        }
        self.publish(NEW_MESSAGE, self.messageCache);
533 534 535 536 537 538 539 540 541
        console.log('render');
        const selectData = result.messages.find(item => { return item.infoLevel == 6 });
        if (selectData) {
          if (this._siteConfig.MessageLevel && this._siteConfig.MessageLevel === "2.0") {
            selectData.Info = self.messageThrome(selectData.infoType, JSON.parse(JSON.stringify(selectData.infoContent)));
          }
          self.renderSysNoticePlatform(selectData)
        }

邓晓峰's avatar
邓晓峰 committed
542 543
        return Promise.resolve(result);
      }
叶飞's avatar
叶飞 committed
544 545
    });
  }
邓晓峰's avatar
邓晓峰 committed
546

邓晓峰's avatar
邓晓峰 committed
547 548
  async getMqttSiteCode() {
    const self = this;
邓晓峰's avatar
邓晓峰 committed
549
    return noticeService.getMqttSiteCode({ 'request.preventCache': Date.now() }).then(
叶飞's avatar
叶飞 committed
550
      res => {
邓晓峰's avatar
邓晓峰 committed
551
        if (res && res.say.statusCode === ERR_OK) {
邓晓峰's avatar
邓晓峰 committed
552 553 554 555 556 557
          let mqttConfig = {
            mqtt_mess: {},
            mqtt_path: self._siteConfig.mqtt_path,
            nginxStart: self._siteConfig.NginxStart,
            mqtt_IsSSL: true
          };
邓晓峰's avatar
邓晓峰 committed
558
          if (Array.isArray(res.getMe) && res.getMe.length > 0) {
邓晓峰's avatar
邓晓峰 committed
559

邓晓峰's avatar
邓晓峰 committed
560
            if (res.getMe[0]) {
邓晓峰's avatar
邓晓峰 committed
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
              const data = res.getMe[0];
              mqttConfig.mqtt_IsSSL =  self._siteConfig.IsSSL = data.IsSSL ? data.IsSSL : false;
              mqttConfig.mqtt_mess.site_code = self._siteConfig.site_code = data.SiteCode || self._siteConfig.site_code;
              mqttConfig.mqtt_mess.TcpIP =  self._siteConfig.TcpIP = data.TcpIP;
              mqttConfig.mqtt_mess.TcpPort = self._siteConfig.TcpPort = data.TcpPort ? parseInt(data.TcpPort) : 8083;
              mqttConfig.mqtt_mess.MessageLevel =  self._siteConfig.MessageLevel = data.MessageLevel ? data.MessageLevel : DEFAULT_PARSE_LEVEL;

              if (data.NginxStart) {
                mqttConfig.NginxStart =  self._siteConfig.NginxStart = data.NginxStart;
                mqttConfig.mqtt_mess.TcpIP = self._siteConfig.mqtt_mess.TcpIP = window.location.hostname;
                mqttConfig.mqtt_mess.TcpPort =  self._siteConfig.mqtt_mess.TcpPort = parseInt(window.location.port);
                mqttConfig.mqtt_path = self._siteConfig.mqtt_path = '/ws/';
              } else {
                mqttConfig.nginxStart = data.NginxStart
              }
            }else {
              mqttConfig.mqtt_mess.TcpIP = self._siteConfig.mqtt_mess.TcpIP = DEFAULT_TCP_IP;
              mqttConfig.mqtt_mess.TcpPort = self._siteConfig.mqtt_mess.TcpPort = DEFAULT_TCP_PORT;
              mqttConfig.mqtt_IsSSL = self._siteConfig.IsSSL = self._siteConfig.mqtt_mess.TcpIP + ":" + self._siteConfig.mqtt_mess.TcpPort;
邓晓峰's avatar
邓晓峰 committed
580
            }
邓晓峰's avatar
邓晓峰 committed
581 582 583 584 585 586 587

            mqttConfig.mqtt_iotIP = self._siteConfig.mqtt_iotIP = mqttConfig.mqtt_mess.TcpIP + ":" + mqttConfig.mqtt_mess.TcpPort;

            self.props.updateConfig && self.props.updateConfig(Object.assign({}, self.props.global, {
              ...mqttConfig
            }))

叶飞's avatar
叶飞 committed
588 589
          }
        } else {
邓晓峰's avatar
邓晓峰 committed
590
          Logger.info('获取mqtt服务器参数失败');
叶飞's avatar
叶飞 committed
591 592 593 594
        }
      },
    );
  }
邓晓峰's avatar
邓晓峰 committed
595 596 597
  getMessageLevel() {
    return this._siteConfig.MessageLevel
  }
邓晓峰's avatar
邓晓峰 committed
598
  generatedId() {
叶飞's avatar
叶飞 committed
599 600
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
      .replace(/[xy]/g, function(c) {
邓晓峰's avatar
邓晓峰 committed
601
        const r = (Math.random() * 16) | 0;
邓晓峰's avatar
邓晓峰 committed
602
        const v = c === 'x' ? r : (r & 0x3) | 0x8;
叶飞's avatar
叶飞 committed
603 604 605 606
        return v.toString(16);
      })
      .toUpperCase();
  }
邓晓峰's avatar
邓晓峰 committed
607 608

  getMessageType(messageType) {
邓晓峰's avatar
邓晓峰 committed
609
    let infoType = MESSAGE_TYPE.SCADA_TYPE;
邓晓峰's avatar
邓晓峰 committed
610 611 612
    switch (messageType) {
      case MESSAGE_TEXT_TYPE.PROJECT_FLOW:
        infoType = MESSAGE_TYPE.CASE_TYPE;
叶飞's avatar
叶飞 committed
613
        break;
邓晓峰's avatar
邓晓峰 committed
614 615 616
      case MESSAGE_TEXT_TYPE.SYS_MESSAGE:
      case MESSAGE_TEXT_TYPE.SYS_NOTICE:
        infoType = MESSAGE_TYPE.SYS_TYPE;
叶飞's avatar
叶飞 committed
617
        break;
邓晓峰's avatar
邓晓峰 committed
618 619
      case MESSAGE_TEXT_TYPE.SAWATER:
        infoType = MESSAGE_TYPE.SAVE_WA_TYPE;
叶飞's avatar
叶飞 committed
620
        break;
邓晓峰's avatar
邓晓峰 committed
621 622
      case MESSAGE_TEXT_TYPE.EMTT:
        infoType = MESSAGE_TYPE.EIMT_TYPE;
叶飞's avatar
叶飞 committed
623
        break;
邓晓峰's avatar
邓晓峰 committed
624 625
      case MESSAGE_TEXT_TYPE.MESSAGE_ALERT:
        infoType = MESSAGE_TYPE.MESSAGE_ALERT;
叶飞's avatar
叶飞 committed
626 627 628 629 630 631
        break;
      default:
        break;
    }
    return infoType;
  }
邓晓峰's avatar
邓晓峰 committed
632

邓晓峰's avatar
邓晓峰 committed
633 634 635
  parseHisToMessage(hisMessage) {
    const timeH = (new Date() - new Date(hisMessage.HisCreateTime)) / 1000 / 60;
    const timeMss =
叶飞's avatar
叶飞 committed
636 637 638
      Math.abs(timeH) > 1440
        ? hisMessage.HisCreateTime.split('.')[0]
        : Math.abs(timeH) > 60
邓晓峰's avatar
邓晓峰 committed
639
        ? `${(timeH / 60).toFixed(0)}小时前`
叶飞's avatar
叶飞 committed
640
        : Math.abs(timeH) > 1
邓晓峰's avatar
邓晓峰 committed
641
        ? `${timeH.toFixed(0)}分钟前`
叶飞's avatar
叶飞 committed
642
        : '刚刚';
邓晓峰's avatar
邓晓峰 committed
643
    const message = {
叶飞's avatar
叶飞 committed
644
      id: hisMessage.HisID,
邓晓峰's avatar
邓晓峰 committed
645
      infoContent: this._siteConfig.MessageLevel === DEFAULT_PARSE_LEVEL ? hisMessage.InfoContent: isJSON(hisMessage.InfoContent) ?  JSON.parse(hisMessage.InfoContent): hisMessage.InfoContent,
叶飞's avatar
叶飞 committed
646
      time: `${timeMss}`,
邓晓峰's avatar
邓晓峰 committed
647
      infoType: this.getMessageType(hisMessage.InfoType),
叶飞's avatar
叶飞 committed
648 649 650 651 652 653
      dateTime: hisMessage.HisCreateTime,
      infoLevel: hisMessage.InfoLevel,
      webConfig: hisMessage.web_config,
      webPath: hisMessage.web_path,
      messType: hisMessage.MessType,
    };
邓晓峰's avatar
邓晓峰 committed
654 655 656 657 658
    if (this.getParseVesion()) {
      message.infoContent = this.parseMessageToJSON(message.infoType, message);
    } else {
      message.infoContent = JSON.parse(
        JSON.stringify(message.infoContent || '{}'),
叶飞's avatar
叶飞 committed
659
      );
邓晓峰's avatar
邓晓峰 committed
660 661
    }
    return createMessage(message);
叶飞's avatar
叶飞 committed
662 663
  }

邓晓峰's avatar
邓晓峰 committed
664 665 666
  getParseVesion() {
    const siteConfig = this.getSiteConfig();
    return !siteConfig.MessageLevel || siteConfig.MessageLevel !== '2.0';
叶飞's avatar
叶飞 committed
667
  }
邓晓峰's avatar
邓晓峰 committed
668 669 670 671 672 673 674

  parseMessageToJSON(messageType, messageContent) {
    let messageBody = messageContent;
    try {
      switch (messageType) {
        case MESSAGE_TYPE.SCADA_TYPE:
          messageBody = this.parseMessageAlarm(messageContent);
叶飞's avatar
叶飞 committed
675
          break;
邓晓峰's avatar
邓晓峰 committed
676 677
        case MESSAGE_TYPE.CASE_TYPE:
          messageBody = this.parseMessageCase(messageContent);
叶飞's avatar
叶飞 committed
678
          break;
邓晓峰's avatar
邓晓峰 committed
679 680
        case MESSAGE_TYPE.SYS_TYPE:
          messageBody = this.parseMessageNotice(messageContent);
叶飞's avatar
叶飞 committed
681
          break;
邓晓峰's avatar
邓晓峰 committed
682
        case MESSAGE_TYPE.SAVE_WA_TYPE:
叶飞's avatar
叶飞 committed
683
          break;
邓晓峰's avatar
邓晓峰 committed
684
        case MESSAGE_TYPE.EIMT_TYPE:
叶飞's avatar
叶飞 committed
685
          break;
邓晓峰's avatar
邓晓峰 committed
686
        case MESSAGE_TYPE.UNKNOWN:
叶飞's avatar
叶飞 committed
687 688 689 690
          break;
        default:
          break;
      }
邓晓峰's avatar
邓晓峰 committed
691 692
    } catch (e) {
      logger.info(
邓晓峰's avatar
邓晓峰 committed
693
        `1.0消息通知解析消息内容出错:${e.message}`,
邓晓峰's avatar
邓晓峰 committed
694 695 696 697
        '消息对象:',
        messString,
      );
    } finally {
叶飞's avatar
叶飞 committed
698
    }
叶飞's avatar
叶飞 committed
699

邓晓峰's avatar
邓晓峰 committed
700
    return messageBody;
叶飞's avatar
叶飞 committed
701
  }
邓晓峰's avatar
邓晓峰 committed
702

邓晓峰's avatar
邓晓峰 committed
703 704 705
  parseMessageCase(messString) {
    const attr = messString.infoContent.split('\\n');
    const caseContent = {
叶飞's avatar
叶飞 committed
706 707 708 709 710 711 712 713
      caseType: attr[0].split('】')[0].split('【')[1],
      flowName: attr[0].split('】')[1],
      nodeName: attr[1],
      content: attr[2],
      time: messString.dateTime,
    };
    return caseContent;
  }
邓晓峰's avatar
邓晓峰 committed
714

邓晓峰's avatar
邓晓峰 committed
715 716 717
  parseMessageAlarm(messString) {
    const attr = messString.infoContent.split('\\n');
    const alarmContent = {
叶飞's avatar
叶飞 committed
718 719 720 721 722 723 724 725 726 727 728 729 730
      alarmType: attr[0].split('】')[0].split('【')[1],
      deviceCode: '',
      alarmDevice: attr[0].split('】')[1],
      alarmContent: attr[1],
      alarmThreshold: attr[2].includes(' / ')
        ? attr[2].split('/')[1].trim(' ')
        : '',
      alarmValue: attr[2].includes(' / ')
        ? attr[2].split('/')[0].trim(' ')
        : attr[2].includes(':')
        ? attr[2].split(':')[1]
        : '',
      time: messString.dateTime,
叶飞's avatar
叶飞 committed
731
    };
叶飞's avatar
叶飞 committed
732
    return alarmContent;
叶飞's avatar
叶飞 committed
733
  }
邓晓峰's avatar
邓晓峰 committed
734

邓晓峰's avatar
邓晓峰 committed
735 736 737
  parseMessageNotice(messString) {
    const attr = messString.infoContent.split('\\n');
    const noticeContent = {
叶飞's avatar
叶飞 committed
738 739 740 741 742 743
      noticeType: attr[0].split('】')[0].split('【')[1],
      noticeTitle: attr[0].split('】')[1],
      noticeContent: attr[1],
      time: messString.dateTime,
    };
    return noticeContent;
叶飞's avatar
叶飞 committed
744
  }
邓晓峰's avatar
邓晓峰 committed
745

邓晓峰's avatar
邓晓峰 committed
746
  parseScadaMessage(message) {
邓晓峰's avatar
邓晓峰 committed
747 748 749 750 751
    const data = message.messContent.split('\\n');
    const last = data[2];
    const alarmType = data[0].split('】')[0].split('【')[1];
    const sensor = data[1];
    const station = data[0].split('】')[1];
邓晓峰's avatar
邓晓峰 committed
752 753
    let lastValue = last;
    if (last.includes(' / ')) {
邓晓峰's avatar
邓晓峰 committed
754 755 756 757 758
      lastValue = '';
      const alaVal = last.split(' / ');
      let newVal = 0;
      let setVal = 0;
      let unit = '';
邓晓峰's avatar
邓晓峰 committed
759
      if (alaVal[0].includes(' ')) {
邓晓峰's avatar
邓晓峰 committed
760 761 762
        newVal = alaVal[0].split(' ')[0] * 1;
        setVal = alaVal[1].split(' ')[0] * 1;
        unit = alaVal[0].split(' ')[1];
邓晓峰's avatar
邓晓峰 committed
763
      } else {
邓晓峰's avatar
邓晓峰 committed
764 765
        newVal = alaVal[0] * 1;
        setVal = alaVal[1] * 1;
邓晓峰's avatar
邓晓峰 committed
766 767 768
      }
      lastValue = Math.abs(setVal - newVal).toFixed(2) + unit;
    } else {
邓晓峰's avatar
邓晓峰 committed
769
      lastValue = `,报警实时值${lastValue}`;
邓晓峰's avatar
邓晓峰 committed
770
    }
邓晓峰's avatar
邓晓峰 committed
771
    let msg = `紧急报警:${station},${alarmType},${sensor}${lastValue},请注意!!!`;
邓晓峰's avatar
邓晓峰 committed
772
    for (let i = 0; i < 3; i++) {
邓晓峰's avatar
邓晓峰 committed
773
      msg += msg;
邓晓峰's avatar
邓晓峰 committed
774
    }
邓晓峰's avatar
邓晓峰 committed
775 776
    const state = new window.SpeechSynthesisUtterance(msg);
    state.lang = 'zh';
邓晓峰's avatar
邓晓峰 committed
777 778 779 780
    state.rate = 1;
    window.speechSynthesis.cancel();
    window.speechSynthesis.speak(state);
  }
叶飞's avatar
叶飞 committed
781 782 783
}

export default Notifier;