Explorar o código

im聊天web版本添加创建群聊功能和修改群属性等功能

fancy %!s(int64=5) %!d(string=hai) anos
pai
achega
686607efa3

+ 5 - 0
o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionConversationUpdate.java

@@ -54,6 +54,11 @@ public class ActionConversationUpdate extends BaseAction {
             }
             if (wi.getPersonList() != null && !wi.getPersonList().isEmpty()) {
                 conversation.setPersonList(wi.getPersonList());
+                if (!conversation.getPersonList().contains(effectivePerson.getDistinguishedName())) {
+                    List<String> list = conversation.getPersonList();
+                    list.add(effectivePerson.getDistinguishedName());
+                    conversation.setPersonList(list);
+                }
             }
             conversation.setUpdateTime(new Date());
             emc.check(conversation, CheckPersistType.all);

+ 5 - 0
o2web/source/x_component_IMV2/$Main/default/chat.html

@@ -1,6 +1,11 @@
 <!-- title -->
 <div class="chat-title" data-o2-element="chatTitleNode">
   <span>{{$.convName}}</span>
+  <div class="o2_im_chat_content_title_more" data-o2-element="chatTitleMoreBtnNode"></div>
+  <div class="o2_im_chat_content_title_menu" data-o2-element="chatTitleMoreMenuNode">
+    <div class="o2_im_chat_content_title_menu_item" data-o2-element="chatTitleMoreMenuItem1Node" data-o2-events="click:tapUpdateConvTitle">修改群名</div>
+    <div class="o2_im_chat_content_title_menu_item" data-o2-element="chatTitleMoreMenuItem2Node" data-o2-events="click:tapUpdateConvMembers">修改成员</div>
+  </div>
 </div>
 <!-- 聊天内容 -->
 <div class="chat-content" data-o2-element="chatContentNode">

BIN=BIN
o2web/source/x_component_IMV2/$Main/default/icons/more.png


+ 4 - 1
o2web/source/x_component_IMV2/$Main/default/im.html

@@ -5,6 +5,9 @@
       <div class="add" data-o2-element="o2ImConvCreateNode" data-o2-events="click:tapCreateSingleConv">
         创建单聊
       </div>
+      <div class="group" data-o2-element="o2ImGroupConvCreateNode" data-o2-events="click:tapCreateGroupConv">
+        创建群聊
+      </div>
       <!-- <div class="search_out">
         <div title="搜索" class="search_icon"></div>
         <div class="search_input_out">
@@ -14,7 +17,7 @@
     </div>
 
     <!-- chat list -->
-    <div data-o2-element="chatItemListNode">
+    <div data-o2-element="chatItemListNode" class="o2_im_chat_list_conv">
 
     </div>
 

+ 52 - 0
o2web/source/x_component_IMV2/$Main/default/style.css

@@ -10,6 +10,11 @@
     float: left; 
     width: 257px; 
     height: 100%; 
+    display: flex;
+    display: -webkit-box;
+    display: -webkit-flex;
+    flex-direction: column;
+    -ms-flex-direction: column;
 }
 .o2_im_chat_list_top {
     margin-bottom: 20px;
@@ -25,7 +30,21 @@
     text-align: center;
     line-height: 40px;
     color: #848484;
+    padding-left: 24px;
+    float: left;
+}
+
+.o2_im_chat_list_top .group {
+  height: 40px;
+  cursor: pointer;
+  margin-left: 14px;
+  text-align: center;
+  line-height: 40px;
+  color: #848484;
+  padding-left: 24px;
+  float: left;
 }
+
 .o2_im_chat_list_top .search_out {
     margin-right: 40px; 
     height: 40px;
@@ -146,6 +165,10 @@
     white-space: nowrap;
     text-overflow:ellipsis;
 }
+.o2_im_chat_list_conv {
+  flex: 1;
+  overflow: auto;
+}
 
 
 .o2_im_chat_content {
@@ -161,6 +184,35 @@
     -ms-flex-direction: column;
 }
 
+.o2_im_chat_content_title_more {
+  background-image: url(../x_component_IMV2/$Main/default/icons/more.png);
+  background-position: center center;
+  background-repeat: no-repeat;
+  height: 30px;
+  width: 64px;
+  float: right;
+  cursor: pointer;
+  display: none;
+}
+
+.o2_im_chat_content_title_menu {
+    width: 98px;
+    position: absolute;
+    right: 24px;
+    top: 61px;
+    background-color: white;
+    border-radius: 12px;
+    box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
+    display: none;
+    z-index: 10000;
+}
+.o2_im_chat_content_title_menu_item {
+  height: 48px;
+  text-align: center;
+  line-height: 48px;
+  cursor: pointer;
+}
+
 
 /* 聊天界面 */
 .chat-emoji-box {

+ 230 - 15
o2web/source/x_component_IMV2/Main.js

@@ -108,6 +108,22 @@ MWF.xApplication.IMV2.Main = new Class({
 		this.conversationId = conv.id;
 		this.chatNode.empty();
 		this.chatNode.loadHtml(url, { "bind": data, "module": this }, function () {
+			var me = layout.session.user.distinguishedName;
+			if (conv.type === "group" && me === conv.adminPerson) {
+				this.chatTitleMoreBtnNode.setStyle("display", "block");
+				this.chatTitleMoreBtnNode.addEvents({
+					"click": function (e) {
+						var display = this.chatTitleMoreMenuNode.getStyle("display");
+						if (display === "none") {
+							this.chatTitleMoreMenuNode.setStyle("display", "block");
+						} else {
+							this.chatTitleMoreMenuNode.setStyle("display", "none");
+						}
+					}.bind(this)
+				});
+			} else {
+				this.chatTitleMoreBtnNode.setStyle("display", "none");
+			}
 			//获取聊天信息
 			this.messageList = [];
 			this.loadMsgListByConvId(1, 20, conv.id);
@@ -115,6 +131,25 @@ MWF.xApplication.IMV2.Main = new Class({
 			scrollFx.toBottom();
 		}.bind(this));
 	},
+	//修改群名
+	tapUpdateConvTitle: function() {
+		this.chatTitleMoreMenuNode.setStyle("display", "none");
+		var form = new MWF.xApplication.IMV2.UpdateConvTitleForm(this, {}, {}, { app: this.app });
+		form.create();
+	},
+	//修改群成员
+	tapUpdateConvMembers: function() {
+		this.chatTitleMoreMenuNode.setStyle("display", "none");
+		var members = [];
+		for (var i = 0; i < this.conversationNodeItemList.length; i++) {
+			var c = this.conversationNodeItemList[i];
+			if (this.conversationId == c.data.id) {
+				members = c.data.personList;
+			}
+		}
+		var form = new MWF.xApplication.IMV2.CreateConversationForm(this, {}, { "title": "修改成员", "personCount": 0, "personSelected": members, "isUpdateMember": true }, { app: this.app });
+		form.create()
+	},
 	//点击发送消息
 	sendMsg: function () {
 		var text = this.chatBottomAreaTextareaNode.value;
@@ -156,9 +191,54 @@ MWF.xApplication.IMV2.Main = new Class({
 	},
 	//点击创建单聊按钮
 	tapCreateSingleConv: function () {
-		var form = new MWF.xApplication.IMV2.SingleForm(this, {}, {}, { app: this.app });
+		// var form = new MWF.xApplication.IMV2.SingleForm(this, {}, {}, { app: this.app });
+		// form.create()
+		var form = new MWF.xApplication.IMV2.CreateConversationForm(this, {}, { "title": "创建单聊", "personCount": 1 }, { app: this.app });
+		form.create()
+	},
+	//点击创建群聊按钮
+	tapCreateGroupConv: function () {
+		var form = new MWF.xApplication.IMV2.CreateConversationForm(this, {}, { "title": "创建群聊", "personCount": 0, "personSelected": [] }, { app: this.app });
 		form.create()
 	},
+	//更新群名
+	updateConversationTitle: function(title, convId) {
+		var conv = {
+			id: convId,
+			title: title,
+		};
+		var _self = this;
+		o2.Actions.load("x_message_assemble_communicate").ImAction.update(conv, function (json) {
+			var newConv = json.data;
+			//点击会话 刷新聊天界面
+			_self.tapConv(newConv);
+			//刷新会话列表的title
+			for (var i = 0; i < this.conversationNodeItemList.length; i++) {
+				var cv = this.conversationNodeItemList[i];
+				if (cv.data.id == convId) {
+					//刷新
+					cv.refreshConvTitle(title);
+				}
+			}
+
+		}.bind(this), function (error) {
+			console.log(error);
+		}.bind(this))
+	},
+	//更新群成员
+	updateConversationMembers: function(members, convId) {
+		var conv = {
+			id: convId,
+			personList: members,
+		};
+		var _self = this;
+		o2.Actions.load("x_message_assemble_communicate").ImAction.update(conv, function (json) {
+			var newConv = json.data;
+			_self.tapConv(newConv);
+		}.bind(this), function (error) {
+			console.log(error);
+		}.bind(this))
+	},
 	/**
 	 * 	创建会话
 	 * @param {*} persons 人员列表
@@ -342,19 +422,19 @@ MWF.xApplication.IMV2.Main = new Class({
 			var url = this._getFileUrlWithWH(msgBody.fileId, 144, 192);
 			new Element("img", { "src": url }).inject(imgBox);
 			imgBox.addEvents({
-				"click": function(e){
+				"click": function (e) {
 					var downloadUrl = this._getFileDownloadUrl(msgBody.fileId);
 					window.open(downloadUrl);
 				}.bind(this)
 			});
 		} else if (msgBody.type == "audio") {
 			var url = this._getFileDownloadUrl(msgBody.fileId);
-			new Element("audio", { "src": url, "controls":"controls", "preload":"preload" }).inject(lastNode);
+			new Element("audio", { "src": url, "controls": "controls", "preload": "preload" }).inject(lastNode);
 		} else if (msgBody.type == "location") {
 			var mapBox = new Element("span").inject(lastNode);
-			new Element("img", { "src": "../x_component_IMV2/$Main/default/icons/location.png", "width":24, "height":24 }).inject(mapBox);
+			new Element("img", { "src": "../x_component_IMV2/$Main/default/icons/location.png", "width": 24, "height": 24 }).inject(mapBox);
 			var url = this._getBaiduMapUrl(msgBody.latitude, msgBody.longitude, msgBody.address, msgBody.addressDetail);
-			new Element("a", {"href":url, "target":"_blank", "text": msgBody.address}).inject(mapBox);
+			new Element("a", { "href": url, "target": "_blank", "text": msgBody.address }).inject(mapBox);
 		} else {//text
 			new Element("span", { "text": msgBody.body }).inject(lastNode);
 		}
@@ -396,19 +476,19 @@ MWF.xApplication.IMV2.Main = new Class({
 			var url = this._getFileUrlWithWH(msgBody.fileId, 144, 192);
 			new Element("img", { "src": url }).inject(imgBox);
 			imgBox.addEvents({
-				"click": function(e){
+				"click": function (e) {
 					var downloadUrl = this._getFileDownloadUrl(msgBody.fileId);
 					window.open(downloadUrl);
 				}.bind(this)
 			});
 		} else if (msgBody.type == "audio") {
 			var url = this._getFileDownloadUrl(msgBody.fileId);
-			new Element("audio", { "src": url, "controls":"controls", "preload":"preload" }).inject(lastNode);
+			new Element("audio", { "src": url, "controls": "controls", "preload": "preload" }).inject(lastNode);
 		} else if (msgBody.type == "location") {
 			var mapBox = new Element("span").inject(lastNode);
-			new Element("img", { "src": "../x_component_IMV2/$Main/default/icons/location.png", "width":24, "height":24 }).inject(mapBox);
+			new Element("img", { "src": "../x_component_IMV2/$Main/default/icons/location.png", "width": 24, "height": 24 }).inject(mapBox);
 			var url = this._getBaiduMapUrl(msgBody.latitude, msgBody.longitude, msgBody.address, msgBody.addressDetail);
-			new Element("a", {"href":url, "target":"_blank", "text": msgBody.address}).inject(mapBox);
+			new Element("a", { "href": url, "target": "_blank", "text": msgBody.address }).inject(mapBox);
 		} else {//text
 			new Element("span", { "text": msgBody.body }).inject(lastNode);
 		}
@@ -419,7 +499,7 @@ MWF.xApplication.IMV2.Main = new Class({
 		}
 	},
 	//图片 根据大小 url
-	_getFileUrlWithWH: function(id, width, height) {
+	_getFileUrlWithWH: function (id, width, height) {
 		var action = MWF.Actions.get("x_message_assemble_communicate").action;
 		var url = action.address + action.actions.imgFileDownloadWithWH.uri;
 		url = url.replace("{id}", encodeURIComponent(id));
@@ -428,15 +508,15 @@ MWF.xApplication.IMV2.Main = new Class({
 		return url;
 	},
 	//file 下载的url
-	_getFileDownloadUrl: function(id) {
+	_getFileDownloadUrl: function (id) {
 		var action = MWF.Actions.get("x_message_assemble_communicate").action;
 		var url = action.address + action.actions.imgFileDownload.uri;
 		url = url.replace("{id}", encodeURIComponent(id));
 		return url;
 	},
 	//百度地图打开地址
-	_getBaiduMapUrl: function(lat, longt, address, content) {
-		var url = "https://api.map.baidu.com/marker?location="+lat+","+longt+"&title="+address+"&content="+content+"&output=html&src=net.o2oa.map";
+	_getBaiduMapUrl: function (lat, longt, address, content) {
+		var url = "https://api.map.baidu.com/marker?location=" + lat + "," + longt + "&title=" + address + "&content=" + content + "&output=html&src=net.o2oa.map";
 		return url;
 	},
 	//用户头像
@@ -580,7 +660,7 @@ MWF.xApplication.IMV2.ConversationItem = new Class({
 		new Element("img", { "src": convData.avatarUrl, "class": "img" }).inject(avatarNode);
 		var bodyNode = new Element("div", { "class": "body" }).inject(this.nodeBaseItem);
 		var bodyUpNode = new Element("div", { "class": "body_up" }).inject(bodyNode);
-		new Element("div", { "class": "body_title", "text": convData.title }).inject(bodyUpNode);
+		this.titleNode = new Element("div", { "class": "body_title", "text": convData.title }).inject(bodyUpNode);
 		this.messageTimeNode = new Element("div", { "class": "body_time", "text": convData.time }).inject(bodyUpNode);
 		if (convData.lastMessageType == "emoji") {
 			this.lastMessageNode = new Element("div", { "class": "body_down" }).inject(bodyNode);
@@ -634,6 +714,9 @@ MWF.xApplication.IMV2.ConversationItem = new Class({
 			this.messageTimeNode.set("text", time);
 		}
 	},
+	refreshConvTitle: function(title) {
+		this.titleNode.set("text", title);
+	},
 	addCheckClass: function () {
 		if (this.nodeBaseItem) {
 			if (!this.nodeBaseItem.hasClass("check")) {
@@ -681,7 +764,7 @@ MWF.xApplication.IMV2.SingleForm = new Class({
 			style: "minder",
 			hasColon: true,
 			itemTemplate: {
-				person: { text: "选择人员", type: "org", orgType: "person", notEmpty: true, exclude: exclude },
+				person: { text: "选择人员", type: "org", orgType: "person", count: 0, notEmpty: true, exclude: exclude },
 			}
 		}, this.app);
 		this.form.load();
@@ -713,4 +796,136 @@ MWF.xApplication.IMV2.SingleForm = new Class({
 			this.close();
 		}
 	}
+});
+
+
+//创建聊天 弹出窗表单
+MWF.xApplication.IMV2.CreateConversationForm = new Class({
+	Extends: MPopupForm,
+	Implements: [Options, Events],
+	options: {
+		"style": "minder",
+		"width": 700,
+		"height": "200",
+		"hasTop": true,
+		"hasIcon": false,
+		"draggable": true,
+		"title": "创建单聊",
+		"personCount": 1, //1 是单选  0 是多选,
+		"personSelected": [],
+		"isUpdateMember": false
+	},
+	_createTableContent: function () {
+		var html = "<table width='100%' bordr='0' cellpadding='7' cellspacing='0' styles='formTable' style='margin-top: 20px; '>" +
+			"<tr><td styles='formTableTitle' lable='person' width='25%'></td>" +
+			"    <td styles='formTableValue14' item='person' colspan='3'></td></tr>" +
+			"</table>";
+		this.formTableArea.set("html", html);
+		var me = layout.session.user.distinguishedName;
+		var exclude = [];
+		if (me) {
+			exclude = [me];
+		}
+		this.form = new MForm(this.formTableArea, this.data || {}, {
+			isEdited: true,
+			style: "minder",
+			hasColon: true,
+			itemTemplate: {
+				person: { text: "选择人员", type: "org", orgType: "person", count: this.options["personCount"], notEmpty: true, exclude: exclude, value: this.options["personSelected"] },
+			}
+		}, this.app);
+		this.form.load();
+
+	},
+	_createBottomContent: function () {
+		if (this.isNew || this.isEdited) {
+			this.okActionNode = new Element("button.inputOkButton", {
+				"styles": this.css.inputOkButton,
+				"text": "确定"
+			}).inject(this.formBottomNode);
+			this.okActionNode.addEvent("click", function (e) {
+				this.save(e);
+			}.bind(this));
+		}
+		this.cancelActionNode = new Element("button.inputCancelButton", {
+			"styles": (this.isEdited || this.isNew || this.getEditPermission()) ? this.css.inputCancelButton : this.css.inputCancelButton_long,
+			"text": "关闭"
+		}).inject(this.formBottomNode);
+		this.cancelActionNode.addEvent("click", function (e) {
+			this.close(e);
+		}.bind(this));
+
+	},
+	save: function () {
+		var data = this.form.getResult(true, null, true, false, true);
+		if (data) {
+			if (this.options["isUpdateMember"] === true) {
+				this.app.updateConversationMembers(data.person, this.app.conversationId);
+			}else {
+				this.app.newConversation(data.person, this.options["personCount"] === 1 ? "single": "group");
+			}
+			
+			this.close();
+		}
+	}
+});
+
+
+
+//修改群名
+MWF.xApplication.IMV2.UpdateConvTitleForm = new Class({
+	Extends: MPopupForm,
+	Implements: [Options, Events],
+	options: {
+		"style": "minder",
+		"width": 500,
+		"height": "200",
+		"hasTop": true,
+		"hasIcon": false,
+		"draggable": true,
+		"title": "修改群名"
+	},
+	_createTableContent: function () {
+		var html = "<table width='100%' bordr='0' cellpadding='7' cellspacing='0' styles='formTable' style='margin-top: 20px; '>" +
+			"<tr><td styles='formTableTitle' lable='title' width='25%'></td>" +
+			"    <td styles='formTableValue14' item='title' colspan='3'></td></tr>" +
+			"</table>";
+		this.formTableArea.set("html", html);
+		 
+		this.form = new MForm(this.formTableArea, this.data || {}, {
+			isEdited: true,
+			style: "minder",
+			hasColon: true,
+			itemTemplate: {
+				title: {text: "群名", type: "text", notEmpty: true },
+			}
+		}, this.app);
+		this.form.load();
+
+	},
+	_createBottomContent: function () {
+		if (this.isNew || this.isEdited) {
+			this.okActionNode = new Element("button.inputOkButton", {
+				"styles": this.css.inputOkButton,
+				"text": "确定"
+			}).inject(this.formBottomNode);
+			this.okActionNode.addEvent("click", function (e) {
+				this.save(e);
+			}.bind(this));
+		}
+		this.cancelActionNode = new Element("button.inputCancelButton", {
+			"styles": (this.isEdited || this.isNew || this.getEditPermission()) ? this.css.inputCancelButton : this.css.inputCancelButton_long,
+			"text": "关闭"
+		}).inject(this.formBottomNode);
+		this.cancelActionNode.addEvent("click", function (e) {
+			this.close(e);
+		}.bind(this));
+	},
+	save: function () {
+		var data = this.form.getResult(true, null, true, false, true);
+		if (data) {
+			this.app.updateConversationTitle(data.title, this.app.conversationId);
+			this.close();
+		}
+	}
 });