pushMessage.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. import Common from './Common.js';
  2. import { h } from 'vue';
  3. import { Notify } from 'pc-component-v3';
  4. import TaskOpenUtil from '../workflow/TaskOpenUtil';
  5. import { Modal, notification } from 'ant-design-vue';
  6. import { MessageTwoTone } from '@ant-design/icons-vue';
  7. import WindowService from './WindowService.js';
  8. export default {
  9. flag: false,
  10. timer: null,
  11. source: null,
  12. isSound: false,
  13. allMessage: [],
  14. webSocket: null,
  15. notificationId: null,
  16. // 触发通知
  17. triggerNotification: function () {
  18. const _self = this;
  19. let token = localStorage.getItem('#token');
  20. if (!token) {
  21. _self.timer = null;
  22. _self.allMessage.splice(0, _self.allMessage.length);
  23. notification.close(_self.notificationId);
  24. return;
  25. }
  26. _self.timer = setInterval(function () {
  27. let allowSound = localStorage.getItem('allowSound');
  28. if (_self.allMessage.length > 0) {
  29. let index = Math.floor(Math.random() * _self.allMessage.length);
  30. let item = _self.allMessage[index];
  31. notification.close(_self.notificationId);
  32. _self.openNotification(item);
  33. _self.isShowNotification(item);
  34. if (!window.opener && window.opener !== window && allowSound == 'true') {
  35. _self.playSound(true);
  36. }
  37. _self.allMessage.splice(index, 1);
  38. } else {
  39. clearInterval(_self.timer);
  40. _self.timer = null;
  41. }
  42. }, 5000);
  43. },
  44. // 播放声音
  45. playSound: async function (isPlay) {
  46. const _self = this;
  47. if (_self.flag && isPlay) {
  48. return;
  49. }
  50. let ctx = new (window.AudioContext || window.webkitAudioContext)();
  51. const audioUrl = '/static/assets/client-base-v4/sound/sound.mp3';
  52. const res = await fetch(audioUrl);
  53. const arrayBuffer = await res.arrayBuffer();
  54. ctx.decodeAudioData(
  55. arrayBuffer,
  56. function (buffer) {
  57. //处理成功返回的数据类型为AudioBuffer
  58. //创建AudioBufferSourceNode对象
  59. _self.source = ctx.createBufferSource();
  60. _self.source.buffer = buffer;
  61. _self.source.connect(ctx.destination);
  62. _self.source.currentTime = 0;
  63. if (isPlay) {
  64. _self.source.start(0);
  65. setTimeout(() => {
  66. _self.source.stop();
  67. _self.flag = false;
  68. }, 5000);
  69. _self.flag = true;
  70. }
  71. },
  72. function (e) {
  73. console.info('处理出错');
  74. },
  75. );
  76. },
  77. // 检验是否支持系统提示
  78. isShowNotification: function (message) {
  79. const _self = this;
  80. // 检查浏览器是否支持 Notification API
  81. if (!('Notification' in window)) {
  82. alert('此浏览器不支持桌面通知');
  83. return;
  84. }
  85. // 检查用户是否已经允许显示通知
  86. if (Notification.permission === 'granted') {
  87. // 如果已经允许,直接显示通知
  88. _self.showNotification(message);
  89. } else if (Notification.permission !== 'denied') {
  90. // 否则,请求用户允许显示通知
  91. Notification.requestPermission().then(permission => {
  92. // 如果用户允许,显示通知
  93. if (permission === 'granted') {
  94. _self.showNotification(message);
  95. }
  96. });
  97. }
  98. },
  99. // 进行系统提示
  100. showNotification: function (message) {
  101. // 创建一个新的 Notification 对象
  102. if (message.type == 'NEW_TASK') {
  103. const notification = new Notification('待处理消息', {
  104. body: message.content.title,
  105. });
  106. // 监听通知的点击事件
  107. notification.onclick = () => {
  108. TaskOpenUtil.openTask(message.content).then(
  109. successData => {
  110. if (successData.type === 'newWindow') {
  111. WindowService.open(successData.url, '待处理');
  112. }
  113. },
  114. errorData => {
  115. if (errorData != null) {
  116. Notify.error(errorData.title, errorData.message, false);
  117. }
  118. },
  119. );
  120. };
  121. } else if (message.type == 'NEW_UserReadDocument') {
  122. const notification = new Notification('待审阅消息', {
  123. body: message.content.title,
  124. });
  125. notification.onclick = () => {
  126. TaskOpenUtil.openTask(message.content).then(
  127. successData => {
  128. if (successData.type === 'newWindow') {
  129. WindowService.open(successData.url, '待处理');
  130. }
  131. },
  132. errorData => {
  133. if (errorData != null) {
  134. Notify.error(errorData.title, errorData.message, false);
  135. }
  136. },
  137. );
  138. };
  139. }
  140. },
  141. // 打开消息提示框
  142. openNotification: function (messageData) {
  143. const _self = this;
  144. _self.notificationId = messageData.uuid;
  145. if (messageData.type == 'NEW_TASK') {
  146. notification.open({
  147. key: messageData.uuid,
  148. message: messageData.content.title,
  149. description: '您有一条待处理消息',
  150. icon: () =>
  151. h(MessageTwoTone, {
  152. style: 'color: #108ee9',
  153. }),
  154. duration: 5,
  155. style: {
  156. marginTop: '30px',
  157. },
  158. onClick: () => {
  159. notification.close(messageData.uuid);
  160. _self.replyMessage(messageData.content.id);
  161. TaskOpenUtil.openTask(messageData.content).then(
  162. successData => {
  163. if (successData.type === 'newWindow') {
  164. WindowService.open(successData.url, '待处理');
  165. }
  166. },
  167. errorData => {
  168. if (errorData != null) {
  169. Notify.error(errorData.title, errorData.message, false);
  170. }
  171. },
  172. );
  173. },
  174. });
  175. } else if (messageData.type == 'NEW_UserReadDocument') {
  176. notification.open({
  177. key: messageData.uuid,
  178. message: messageData.content.title,
  179. description: '您有一条待审阅消息',
  180. icon: () =>
  181. h(MessageTwoTone, {
  182. style: 'color: #108ee9',
  183. }),
  184. duration: 5,
  185. onClick: () => {
  186. notification.close(messageData.uuid);
  187. _self.replyDocument(messageData.content.id);
  188. TaskOpenUtil.openCopyTask(messageData.content).then(
  189. successData => {
  190. if (successData.type === 'newWindow') {
  191. WindowService.open(successData.url, '抄送我的', function () {
  192. console.log('打开审阅单');
  193. });
  194. }
  195. },
  196. errorData => {
  197. if (errorData != null) {
  198. Notify.error(errorData.title, errorData.message, false);
  199. }
  200. },
  201. );
  202. },
  203. });
  204. }
  205. },
  206. // 确认收到待处理消息
  207. replyMessage: function (id) {
  208. let requestUrl = 'UnPushTaskResource/Task?id=' + id;
  209. $.ajax({
  210. url: Common.getApiURL(requestUrl),
  211. type: 'get',
  212. dataType: 'json',
  213. beforeSend: function (request) {
  214. Common.addTokenToRequest(request);
  215. },
  216. success: function (data) {
  217. // console.log(data, 'data---------');
  218. },
  219. error: function (XMLHttpRequest, textStatus, errorThrown) {
  220. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  221. },
  222. });
  223. },
  224. // 确认收到待审阅消息
  225. replyDocument: function (id) {
  226. let requestUrl = 'UnPushTaskResource/UserReadDocument?id=' + id;
  227. $.ajax({
  228. url: Common.getApiURL(requestUrl),
  229. type: 'get',
  230. dataType: 'json',
  231. beforeSend: function (request) {
  232. Common.addTokenToRequest(request);
  233. },
  234. success: function (data) {
  235. // console.log(data, 'data---------');
  236. },
  237. error: function (XMLHttpRequest, textStatus, errorThrown) {
  238. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  239. },
  240. });
  241. },
  242. // 弹出打开声音提示框
  243. messageModal: function () {
  244. const _self = this;
  245. Modal.warning({
  246. okText: '确认',
  247. title: '温馨提示',
  248. content: '您的浏览器设置,提示音无法自动播放,请您点击【确认】按钮,可以自动播放提示音。',
  249. onOk() {
  250. _self.playSound(false);
  251. localStorage.setItem('allowSound', true);
  252. },
  253. });
  254. },
  255. // 触发仪表盘数量更新事件
  256. executionEvent: function () {
  257. // 获取刷新元素
  258. const refreshElement = document.querySelector('#refreshCount');
  259. // 自定义事件
  260. const customEvent = new CustomEvent('evt');
  261. // 触发事件
  262. window.refreshTimer = setInterval(function () {
  263. refreshElement.dispatchEvent(customEvent);
  264. clearInterval(window.refreshTimer);
  265. window.refreshTimer = null;
  266. }, 10000);
  267. },
  268. // 打开websocket
  269. openWebSocket: function () {
  270. const _self = this;
  271. // 如果websocket已连接就不在连接
  272. if (_self.webSocket && _self.webSocket.readyState == 1) {
  273. return;
  274. }
  275. let token = localStorage.getItem('#token');
  276. let websocketUrl = Common.getHostPageBaseURL() + 'WebSocket/MessageQueue';
  277. if (websocketUrl.indexOf('https') == 0) {
  278. websocketUrl = websocketUrl.replace('https', 'wss').replace('/api', '');
  279. } else if (websocketUrl.indexOf('http') == 0) {
  280. websocketUrl = websocketUrl.replace('http', 'ws').replace('/api', '');
  281. }
  282. _self.webSocket = new WebSocket(websocketUrl, [token]);
  283. _self.webSocket.onopen = function () {
  284. console.log('websocket打开');
  285. };
  286. _self.webSocket.onmessage = function (message) {
  287. let taskData = JSON.parse(message.data);
  288. console.log('websocket 收到信息 : ' + taskData);
  289. if (taskData) {
  290. _self.allMessage.push(taskData);
  291. }
  292. if (_self.timer == null) {
  293. _self.triggerNotification();
  294. }
  295. if (!window.refreshTimer) {
  296. _self.executionEvent();
  297. }
  298. _self.webSocket.send(message.data);
  299. };
  300. _self.webSocket.onclose = function () {
  301. console.log('websocket关闭');
  302. _self.webSocket = null;
  303. };
  304. _self.webSocket.onerror = function (event) {
  305. console.log('websocket异常');
  306. _self.webSocket.close();
  307. };
  308. },
  309. // 注销后关闭websocket和循环
  310. closeWebsocket: function () {
  311. const _self = this;
  312. if (_self.webSocket) {
  313. _self.webSocket.close();
  314. clearInterval(_self.timer);
  315. clearInterval(window.refreshTimer);
  316. _self.timer = null;
  317. _self.webSocket = null;
  318. window.refreshTimer = null;
  319. _self.allMessage.splice(0, _self.allMessage.length);
  320. notification.close(_self.notificationId);
  321. }
  322. },
  323. };