Main.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. MWF.require("MWF.widget.UUID", null, false);
  2. MWF.xDesktop.requireApp("Template", "MForm", null, false);
  3. MWF.xDesktop.requireApp("Template", "MPopupForm", null, false);
  4. MWF.xApplication.IMV2.Main = new Class({
  5. Extends: MWF.xApplication.Common.Main,
  6. Implements: [Options, Events],
  7. options: {
  8. "style": "default",
  9. "name": "IMV2",
  10. "mvcStyle": "style.css",
  11. "icon": "icon.png",
  12. "width": "1024",
  13. "height": "768",
  14. "isResize": true,
  15. "isMax": true,
  16. "title": MWF.xApplication.IMV2.LP.title,
  17. "conversationId":""
  18. },
  19. onQueryLoad: function () {
  20. this.lp = MWF.xApplication.IMV2.LP;
  21. this.app = this;
  22. this.conversationNodeItemList = [];
  23. this.conversationId = this.options.conversationId || "";
  24. this.messageList = [];
  25. },
  26. onQueryClose: function(){
  27. console.log("关闭聊天窗口。。。。");
  28. this.closeListening()
  29. },
  30. loadApplication: function (callback) {
  31. var url = this.path + this.options.style + "/im.html";
  32. this.content.loadHtml(url, { "bind": { "lp": this.lp, "data": {} }, "module": this }, function () {
  33. //设置content
  34. this.app.content = this.o2ImMainNode;
  35. //启动监听
  36. this.startListening();
  37. //获取会话列表
  38. this.conversationNodeItemList = [];
  39. o2.Actions.load("x_message_assemble_communicate").ImAction.myConversationList(function (json) {
  40. if (json.data && json.data instanceof Array) {
  41. this.loadConversationList(json.data);
  42. }
  43. }.bind(this));
  44. }.bind(this));
  45. },
  46. startListening:function(){
  47. this.messageNumber = layout.desktop.message.items.length;
  48. //查询ws消息 如果增加
  49. if (this.listener) {
  50. clearInterval(this.listener);
  51. }
  52. this.listener = setInterval(function(){
  53. var newNumber = layout.desktop.message.items.length;
  54. //判断是否有新的ws消息
  55. if(newNumber > this.messageNumber) {
  56. //查询会话数据
  57. this._checkConversationMessage();
  58. //查询聊天数据
  59. this._checkNewMessage();
  60. this.messageNumber = newNumber;
  61. }
  62. }.bind(this), 1000);
  63. },
  64. closeListening: function() {
  65. if (this.listener) {
  66. clearInterval(this.listener);
  67. }
  68. },
  69. //加载会话列表
  70. loadConversationList: function (list) {
  71. for (var i = 0; i < list.length; i++) {
  72. var chat = list[i];
  73. var itemNode = this._createConvItemNode(chat);
  74. this.conversationNodeItemList.push(itemNode);
  75. if(this.conversationId && this.conversationId == chat.id) {
  76. this.tapConv(chat);
  77. }
  78. }
  79. console.log("结束");
  80. },
  81. //分页获取会话的消息列表数据
  82. loadMsgListByConvId: function (page, size, convId) {
  83. var data = { "conversationId": convId };
  84. o2.Actions.load("x_message_assemble_communicate").ImAction.msgListByPaging(page, size, data, function (json) {
  85. var list = json.data;
  86. for (var i = 0; i < list.length; i++) {
  87. this.messageList.push(list[i]);
  88. this._buildMsgNode(list[i], true);
  89. }
  90. console.log("聊天信息添加结束!");
  91. }.bind(this), function (error) {
  92. console.log(error);
  93. }.bind(this), false);
  94. },
  95. //点击会话
  96. tapConv: function (conv) {
  97. this._setCheckNode(conv);
  98. var url = this.path + this.options.style + "/chat.html";
  99. var data = { "convName": conv.title };
  100. this.conversationId = conv.id;
  101. this.chatNode.empty();
  102. this.chatNode.loadHtml(url, { "bind": data, "module": this }, function () {
  103. //获取聊天信息
  104. this.messageList = [];
  105. this.loadMsgListByConvId(1, 20, conv.id);
  106. console.log("开始滚动!!!");
  107. var scrollFx = new Fx.Scroll(this.chatContentNode);
  108. scrollFx.toBottom();
  109. }.bind(this));
  110. },
  111. //点击发送消息
  112. sendMsg: function () {
  113. var text = this.chatBottomAreaTextareaNode.value;
  114. console.log(text);
  115. if (text) {
  116. this.chatBottomAreaTextareaNode.value = "";
  117. this._newAndSendTextMsg(text);
  118. } else {
  119. console.log("没有消息内容!");
  120. }
  121. },
  122. //点击创建单聊按钮
  123. tapCreateSingleConv: function () {
  124. console.log("click tapCreateSingleConv................");
  125. var form = new MWF.xApplication.IMV2.SingleForm(this, {}, {}, { app: this.app });
  126. form.create()
  127. },
  128. /**
  129. * 创建会话
  130. * @param {*} persons 人员列表
  131. * @param {*} cType 会话类型 "single" "group"
  132. */
  133. newConversation: function (persons, cType) {
  134. var conv = {
  135. type: cType,
  136. personList: persons,
  137. };
  138. var _self = this;
  139. o2.Actions.load("x_message_assemble_communicate").ImAction.create(conv, function (json) {
  140. var newConv = json.data;
  141. var isOld = false;
  142. for (var i = 0; i < _self.conversationNodeItemList.length; i++) {
  143. var c = _self.conversationNodeItemList[i];
  144. if (newConv.id == c.data.id) {
  145. isOld = true;
  146. _self.tapConv(c);
  147. }
  148. }
  149. if(!isOld) {
  150. var itemNode = _self._createConvItemNode(newConv);
  151. _self.conversationNodeItemList.push(itemNode);
  152. _self.tapConv(newConv);
  153. }
  154. console.log("创建会话 结束。。。。。");
  155. }.bind(this), function (error) {
  156. console.log(error);
  157. }.bind(this))
  158. },
  159. //创建会话ItemNode
  160. _createConvItemNode: function (conv) {
  161. return new MWF.xApplication.IMV2.ConversationItem(conv, this);
  162. },
  163. //会话ItemNode 点击背景色
  164. _setCheckNode: function (conv) {
  165. for (var i = 0; i < this.conversationNodeItemList.length; i++) {
  166. var item = this.conversationNodeItemList[i];
  167. if (item.data.id == conv.id) {
  168. item.addCheckClass();
  169. } else {
  170. item.removeCheckClass();
  171. }
  172. }
  173. },
  174. //创建文本消息 并发送
  175. _newAndSendTextMsg: function (text) {
  176. var distinguishedName = layout.session.user.distinguishedName;
  177. var time = this._currentTime();
  178. var body = { "body": text };
  179. var bodyJson = JSON.stringify(body);
  180. var uuid = (new MWF.widget.UUID).toString();
  181. var textMessage = {
  182. "id": uuid,
  183. "conversationId": this.conversationId,
  184. "body": bodyJson,
  185. "createPerson": distinguishedName,
  186. "createTime": time,
  187. "sendStatus": 1
  188. };
  189. o2.Actions.load("x_message_assemble_communicate").ImAction.msgCreate(textMessage,
  190. function (json) {
  191. //data = json.data;
  192. console.log("消息发送成功!");
  193. }.bind(this),
  194. function (error) {
  195. console.log(error);
  196. }.bind(this));
  197. this.messageList.push(textMessage);
  198. this._buildSender(body, distinguishedName, false);
  199. this._refreshConvMessage(textMessage);
  200. },
  201. //刷新会话Item里面的最后消息内容
  202. _refreshConvMessage: function(msg) {
  203. for (var i = 0; i < this.conversationNodeItemList.length; i++) {
  204. var node = this.conversationNodeItemList[i];
  205. if (node.data.id == this.conversationId) {
  206. node.refreshLastMsg(msg);
  207. }
  208. }
  209. },
  210. //检查会话列表是否有更新
  211. _checkConversationMessage: function() {
  212. o2.Actions.load("x_message_assemble_communicate").ImAction.myConversationList(function (json) {
  213. if (json.data && json.data instanceof Array) {
  214. var newConList = json.data;
  215. console.log(newConList);
  216. for (var j = 0; j < newConList.length; j++) {
  217. var nCv = newConList[j];
  218. var isNew = true;
  219. for (var i = 0; i < this.conversationNodeItemList.length; i++) {
  220. var cv = this.conversationNodeItemList[i];
  221. if (cv.data.id == nCv.id) {
  222. isNew = false;
  223. //刷新
  224. cv.refreshLastMsg(nCv.lastMessage);
  225. }
  226. }
  227. //新会话 创建
  228. if(isNew) {
  229. var itemNode = this._createConvItemNode(nCv);
  230. this.conversationNodeItemList.push(itemNode);
  231. }
  232. }
  233. //this.loadConversationList(json.data);
  234. }
  235. }.bind(this));
  236. },
  237. //检查是否有新消息
  238. _checkNewMessage: function() {
  239. if (this.conversationId && this.conversationId != "") {//是否有会话窗口
  240. var data = { "conversationId": this.conversationId };
  241. o2.Actions.load("x_message_assemble_communicate").ImAction.msgListByPaging(1, 10, data, function (json) {
  242. var list = json.data;
  243. if(list && list.length > 0) {
  244. var msg = list[0];
  245. //检查聊天框是否有变化
  246. if (this.conversationId == msg.conversationId) {
  247. for (var i = 0; i < list.length; i++) {
  248. var isnew = true;
  249. var m = list[i];
  250. for (var j = 0; j < this.messageList.length; j++) {
  251. if(this.messageList[j].id == m.id) {
  252. isnew = false;
  253. }
  254. }
  255. if(isnew) {
  256. this.messageList.push(m);
  257. this._buildMsgNode(m, false);
  258. // this._refreshConvMessage(m);
  259. }
  260. }
  261. }
  262. }
  263. }.bind(this), function (error) {
  264. console.log(error);
  265. }.bind(this), false);
  266. }
  267. },
  268. //创建消息html节点
  269. _buildMsgNode: function (msg, isTop) {
  270. var createPerson = msg.createPerson;
  271. var jsonbody = msg.body;
  272. var body = JSON.parse(jsonbody);//todo 目前只有一种text类型
  273. var distinguishedName = layout.session.user.distinguishedName;
  274. if (createPerson != distinguishedName) {
  275. this._buildReceiver(body, createPerson, isTop);
  276. } else {
  277. this._buildSender(body, createPerson, isTop);
  278. }
  279. },
  280. /**
  281. * 消息发送体
  282. * @param msgBody 消息体
  283. * @param createPerson 消息人员
  284. * @param isTop 是否放在顶部
  285. */
  286. _buildSender: function (msgBody, createPerson, isTop) {
  287. var receiverBodyNode = new Element("div", { "class": "chat-sender" }).inject(this.chatContentNode, isTop ? "top" : "bottom");
  288. var avatarNode = new Element("div").inject(receiverBodyNode);
  289. var avatarUrl = this._getIcon(createPerson);
  290. var name = createPerson;
  291. if (createPerson.indexOf("@") != -1) {
  292. name = name.substring(0, createPerson.indexOf("@"));
  293. }
  294. var avatarImg = new Element("img", { "src": avatarUrl }).inject(avatarNode);
  295. var nameNode = new Element("div", { "text": name }).inject(receiverBodyNode);
  296. var lastNode = new Element("div").inject(receiverBodyNode);
  297. var lastFirstNode = new Element("div", { "class": "chat-left_triangle" }).inject(lastNode);
  298. //text
  299. var lastSecNode = new Element("span", { "text": msgBody.body }).inject(lastNode);
  300. if(!isTop) {
  301. var scrollFx = new Fx.Scroll(this.chatContentNode);
  302. scrollFx.toBottom();
  303. }
  304. },
  305. /**
  306. * 消息接收体
  307. * @param msgBody
  308. * @param createPerson 消息人员
  309. * @param isTop 是否放在顶部
  310. */
  311. _buildReceiver: function (msgBody, createPerson, isTop) {
  312. var receiverBodyNode = new Element("div", { "class": "chat-receiver" }).inject(this.chatContentNode, isTop ? "top" : "bottom");
  313. var avatarNode = new Element("div").inject(receiverBodyNode);
  314. var avatarUrl = this._getIcon(createPerson);
  315. var name = createPerson;
  316. if (createPerson.indexOf("@") != -1) {
  317. name = name.substring(0, createPerson.indexOf("@"));
  318. }
  319. var avatarImg = new Element("img", { "src": avatarUrl }).inject(avatarNode);
  320. var nameNode = new Element("div", { "text": name }).inject(receiverBodyNode);
  321. var lastNode = new Element("div").inject(receiverBodyNode);
  322. var lastFirstNode = new Element("div", { "class": "chat-right_triangle" }).inject(lastNode);
  323. //text
  324. var lastSecNode = new Element("span", { "text": msgBody.body }).inject(lastNode);
  325. if(!isTop) {
  326. var scrollFx = new Fx.Scroll(this.chatContentNode);
  327. scrollFx.toBottom();
  328. }
  329. },
  330. //用户头像
  331. _getIcon: function (id) {
  332. var orgAction = MWF.Actions.get("x_organization_assemble_control")
  333. var url = (id) ? orgAction.getPersonIcon(id) : "/x_component_IMV2/$Main/default/icons/group.png";
  334. return url + "?" + (new Date().getTime());
  335. },
  336. //输出特殊的时间格式
  337. _friendlyTime: function (date) {
  338. var day = date.getDate();
  339. var monthIndex = date.getMonth();
  340. var year = date.getFullYear();
  341. var time = date.getTime();
  342. var today = new Date();
  343. var todayDay = today.getDate();
  344. var todayMonthIndex = today.getMonth();
  345. var todayYear = today.getFullYear();
  346. var todayTime = today.getTime();
  347. var retTime = "";
  348. //同一天
  349. if (day === todayDay && monthIndex === todayMonthIndex && year === todayYear) {
  350. var hour = 0;
  351. if (todayTime > time) {
  352. hour = parseInt((todayTime - time) / 3600000);
  353. if (hour == 0) {
  354. retTime = Math.max(parseInt((todayTime - time) / 60000), 1) + "分钟前"
  355. } else {
  356. retTime = hour + "小时前"
  357. }
  358. }
  359. return retTime;
  360. }
  361. var dates = parseInt(time / 86400000);
  362. var todaydates = parseInt(todayTime / 86400000);
  363. if (todaydates > dates) {
  364. var days = (todaydates - dates);
  365. if (days == 1) {
  366. retTime = "昨天";
  367. } else if (days == 2) {
  368. retTime = "前天 ";
  369. } else if (days > 2 && days < 31) {
  370. retTime = days + "天前";
  371. } else if (days >= 31 && days <= 2 * 31) {
  372. retTime = "一个月前";
  373. } else if (days > 2 * 31 && days <= 3 * 31) {
  374. retTime = "2个月前";
  375. } else if (days > 3 * 31 && days <= 4 * 31) {
  376. retTime = "3个月前";
  377. } else {
  378. retTime = this._formatDate(date);
  379. }
  380. }
  381. return retTime;
  382. },
  383. //yyyy-MM-dd
  384. _formatDate: function (date) {
  385. var month = date.getMonth() + 1;
  386. var day = date.getDate();
  387. month = (month.toString().length == 1) ? ("0" + month) : month;
  388. day = (day.toString().length == 1) ? ("0" + day) : day;
  389. return date.getFullYear() + '-' + month + '-' + day;
  390. },
  391. //当前时间 yyyy-MM-dd HH:mm:ss
  392. _currentTime: function () {
  393. var today = new Date();
  394. var year = today.getFullYear(); //得到年份
  395. var month = today.getMonth();//得到月份
  396. var date = today.getDate();//得到日期
  397. var hour = today.getHours();//得到小时
  398. var minu = today.getMinutes();//得到分钟
  399. var sec = today.getSeconds();//得到秒
  400. month = month + 1;
  401. if (month < 10) month = "0" + month;
  402. if (date < 10) date = "0" + date;
  403. if (hour < 10) hour = "0" + hour;
  404. if (minu < 10) minu = "0" + minu;
  405. if (sec < 10) sec = "0" + sec;
  406. return year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec;
  407. }
  408. });
  409. //会话对象
  410. MWF.xApplication.IMV2.ConversationItem = new Class({
  411. initialize: function (data, main) {
  412. this.data = data;
  413. this.main = main;
  414. this.container = this.main.chatItemListNode;
  415. this.load();
  416. },
  417. load: function () {
  418. var avatarDefault = this.main._getIcon();
  419. var convData = {
  420. "id": this.data.id,
  421. "avatarUrl": avatarDefault,
  422. "title": this.data.title,
  423. "time": "",
  424. "lastMessage": ""
  425. };
  426. var distinguishedName = layout.session.user.distinguishedName;
  427. if (this.data.type && this.data.type === "single") {
  428. var chatPerson = "";
  429. if (this.data.personList && this.data.personList instanceof Array) {
  430. for (var j = 0; j < this.data.personList.length; j++) {
  431. var person = this.data.personList[j];
  432. if (person !== distinguishedName) {
  433. chatPerson = person;
  434. }
  435. }
  436. }
  437. convData.avatarUrl = this.main._getIcon(chatPerson);
  438. var name = chatPerson;
  439. if (chatPerson.indexOf("@") != -1) {
  440. name = name.substring(0, chatPerson.indexOf("@"));
  441. }
  442. convData.title = name;
  443. }
  444. if (this.data.lastMessage) {
  445. //todo 其它消息类型
  446. var mBody = JSON.parse(this.data.lastMessage.body);
  447. convData.lastMessage = mBody.body;
  448. if (this.data.lastMessage.createTime) {
  449. var time = this.main._friendlyTime(o2.common.toDate(this.data.lastMessage.createTime));
  450. convData.time = time;
  451. }
  452. }
  453. this.node = new Element("div", { "class": "item" }).inject(this.container);
  454. this.nodeBaseItem = new Element("div", { "class": "base" }).inject(this.node);
  455. var avatarNode = new Element("div", { "class": "avatar" }).inject(this.nodeBaseItem);
  456. new Element("img", { "src": convData.avatarUrl, "class": "img" }).inject(avatarNode);
  457. var bodyNode = new Element("div", { "class": "body" }).inject(this.nodeBaseItem);
  458. var bodyUpNode = new Element("div", { "class": "body_up" }).inject(bodyNode);
  459. new Element("div", { "class": "body_title", "text": convData.title }).inject(bodyUpNode);
  460. this.messageTimeNode = new Element("div", { "class": "body_time", "text": convData.time }).inject(bodyUpNode);
  461. this.lastMessageNode = new Element("div", { "class": "body_down", "text": convData.lastMessage }).inject(bodyNode);
  462. var _self = this;
  463. this.node.addEvents({
  464. "click": function () {
  465. _self.main.tapConv(_self.data);
  466. }
  467. });
  468. },
  469. /**
  470. * {
  471. "id": uuid,
  472. "conversationId": this.conversationId,
  473. "body": bodyJson,
  474. "createPerson": distinguishedName,
  475. "createTime": time,
  476. "sendStatus": 1
  477. };
  478. * 刷新会话列表的最后消息内容
  479. * @param {*} lastMessage
  480. */
  481. refreshLastMsg: function(lastMessage) {
  482. //目前是text 类型的消息
  483. var jsonbody = lastMessage.body;
  484. var body = JSON.parse(jsonbody);//todo 目前只有一种text类型
  485. if(this.lastMessageNode) {
  486. this.lastMessageNode.set('text', body.body);
  487. }
  488. var time = this.main._friendlyTime(o2.common.toDate(lastMessage.createTime));
  489. if(this.messageTimeNode) {
  490. this.messageTimeNode.set("text", time);
  491. }
  492. },
  493. addCheckClass: function () {
  494. if (this.nodeBaseItem) {
  495. if (!this.nodeBaseItem.hasClass("check")) {
  496. this.nodeBaseItem.addClass("check");
  497. }
  498. }
  499. },
  500. removeCheckClass: function () {
  501. if (this.nodeBaseItem) {
  502. if (this.nodeBaseItem.hasClass("check")) {
  503. this.nodeBaseItem.removeClass("check");
  504. }
  505. }
  506. }
  507. });
  508. //弹出窗 表单 单聊创建的form
  509. MWF.xApplication.IMV2.SingleForm = new Class({
  510. Extends: MPopupForm,
  511. Implements: [Options, Events],
  512. options: {
  513. "style": "minder",
  514. "width": 700,
  515. //"height": 300,
  516. "height": "200",
  517. "hasTop": true,
  518. "hasIcon": false,
  519. "draggable": true,
  520. "title": "创建单聊"
  521. },
  522. _createTableContent: function () {
  523. var html = "<table width='100%' bordr='0' cellpadding='7' cellspacing='0' styles='formTable' style='margin-top: 20px; '>" +
  524. "<tr><td styles='formTableTitle' lable='person' width='25%'></td>" +
  525. " <td styles='formTableValue14' item='person' colspan='3'></td></tr>" +
  526. "</table>";
  527. this.formTableArea.set("html", html);
  528. var me = layout.session.user.distinguishedName;
  529. var exclude = [];
  530. if (me) {
  531. exclude = [me];
  532. }
  533. this.form = new MForm(this.formTableArea, this.data || {}, {
  534. isEdited: true,
  535. style: "minder",
  536. hasColon: true,
  537. itemTemplate: {
  538. person: { text: "选择人员", type: "org", orgType: "person", notEmpty: true, exclude: exclude },
  539. }
  540. }, this.app);
  541. this.form.load();
  542. },
  543. _createBottomContent: function () {
  544. if (this.isNew || this.isEdited) {
  545. this.okActionNode = new Element("button.inputOkButton", {
  546. "styles": this.css.inputOkButton,
  547. "text": "确定"
  548. }).inject(this.formBottomNode);
  549. this.okActionNode.addEvent("click", function (e) {
  550. this.save(e);
  551. }.bind(this));
  552. }
  553. this.cancelActionNode = new Element("button.inputCancelButton", {
  554. "styles": (this.isEdited || this.isNew || this.getEditPermission()) ? this.css.inputCancelButton : this.css.inputCancelButton_long,
  555. "text": "关闭"
  556. }).inject(this.formBottomNode);
  557. this.cancelActionNode.addEvent("click", function (e) {
  558. this.close(e);
  559. }.bind(this));
  560. },
  561. save: function () {
  562. var data = this.form.getResult(true, null, true, false, true);
  563. if (data) {
  564. console.log(data);
  565. this.app.newConversation(data.person, "single");
  566. this.close();
  567. }
  568. }
  569. });