上一章我简单介绍了融云的配置,融云单聊处理等功能。
本章写了融云的历史记录存储,未读消息,页面刷新处理再聊关系等功能。
历史消息记录存储:
用户或者管理员在发送消息的时候,将消息内容存储到数据库中。
备注:此功能是直接连接数据库存储,优化方案应该存储到本地,但是页面刷新的时候,优先读取本地聊天记录,如果存储的是json格式,则需要自动解析,并取出对应的数据,存放到页面上,当数据交少时,则可以处理,数据过多时,则需要逻辑判断处理。融云api历史记录存储时间隔一小时,如果采取本地存储,也可以延迟存储到数据库中。我是直接采用存储到数据库。
新增常量
<script type="text/javascript">
//记录常量
var hisHtmls = "";
var toUserId = "";//接收人
var sendOutId = "";//发送人
</script>
新增页面刷新关闭jquery功能
<script type="text/javascript">
//如果当前页面被刷新了,则进行再聊状态重置,仅限管理员用户
$(window).unload(function(){
if("manager" == '${identity}'){
//则将再聊状态取消掉
$.post("${ctx}/webMessageUserList/updateCancelMasterState.htmls",
{
master_only_md5:'${currUserId}'
},function(data){
});
}
});
</script>
该功能主要针对管理端,如果客服刷新了页面,则将管理员与所有用户的再聊状态清空掉。
再聊:即管理员和用户正在聊天中,内容也是显示管理员和用户的聊天记录。我这边定义为再聊。
var conversationtype = RongIMLib.ConversationType.PRIVATE; // 私聊
var targetId = $("#toUserId").val(); //目标 Id
var msg = new RongIMLib.TextMessage({content:sendMsg,extra:sendOutId});
var conversationtype = RongIMLib.ConversationType.PRIVATE; // 单聊,其他会话选择相应的消息类型即可。
var pushData = "your pushInfo";//这个暂时还没研究
上一章 extra:这里面填写的是文字,本次采用存储发送人唯一id,即存储到融云的id,
该功能用来监听器接收时使用,下面有谈到。
RongIMClient.getInstance().sendMessage(conversationtype, targetId, msg, {
onSuccess: function (message) {
//发送成功后,将该条发送的消息记录到数据库中
//如果数据库插入成功,则进行页面的发送消息append到html聊天框里。
if("users" == '${identity}'){
$.post("${ctx}/webMessage/insertWebMessageUsers.htmls",
{
users_only_md5:sendOutId,
master_only_md5:targetId,
user_content:message.content.content,
master_content:""
},function(data){
var obj = eval(data);
if(obj.code == 90000){
alert("消息发送失败!");
return;
}else{
var htmls = "<div class=\"rightd\">"+
"<div style=\"float:right;\">"+
"<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
"</div>"+
"<div class=\"speech right\" style=\"margin-right:61px;\">"+message.content.content+"</div>"+
"</div>";
$("#liaotian").append(htmls);
var sendMsg = $("#sendMessage").val("");
$('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
}
});
}else{
$.post("${ctx}/webMessage/insertWebMessageUsers.htmls",
{
users_only_md5:targetId,
master_only_md5:sendOutId,
user_content:"",
master_content:message.content.content
},function(data){
var obj = eval(data);
if(obj.code == 90000){
alert("消息发送失败!");
return;
}else{
var htmls = "<div class=\"rightd\">"+
"<div style=\"float:right;\">"+
"<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
"</div>"+
"<div class=\"speech right\" style=\"margin-right:61px;\">"+message.content.content+"</div>"+
"</div>";
$("#liaotian").append(htmls);
var sendMsg = $("#sendMessage").val("");
$('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
}
});
}
},
onError: function (errorCode,message) {
console.log(message.content.content);
}
}, false, pushData
);
因为本地是用双网页对聊,所以需要判断用户和管理员。当接入到app端时,则网页定义为管理员端,则不需要进行用户判断。
我是优先判断记录是否插入成功,然后在进行页面数据展示。
java代码暂时没有粘贴出来。
发送消息好了之后,那么就是监听消息了:
// 消息监听器
RongIMClient.setOnReceiveMessageListener({
// 接收到的消息
onReceived: function (message) {
// 判断消息类型
var id = message.content.extra;//发送人
sendOutId = "${currUserId}";//当前接收人
//用来查询是否处于聊天状态中
//因为目前用2个网页来聊天,所以需要判断用户和管理员
//等之后接入到app端,则网页永远是管理员,则不需要进行用户判断。
//所以目前就只能繁琐一点。
if("users" == '${identity}'){
$.post("${ctx}/webMessageUserList/selectMasterUsersState.htmls",
{
users_only_md5:sendOutId,
master_only_md5:id
},function(data){
var obj = eval(data);
if(obj.code == 90000){
getNewMsgUser(id);
}else if(obj.entity == 0){
$("#"+id).html(parseInt($("#"+id).html())+1);
//页面执行了+1功能,
//数据库里要存放该数据,如果管理端进行了页面刷新,需要获取数据库里未读数据填充到页面上
}else{
var htmls = "<div class=\"leftd\">"+
"<div style=\"float:left;\">"+
"<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
"</div>"+
"<div class=\"speech left\" style=\"margin-left:61px;\">"+message.content.content+"</div>"+
"</div>";
$("#liaotian").append(htmls);
}
$('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
});
}else{
$.post("${ctx}/webMessageUserList/selectMasterUsersState.htmls",
{
users_only_md5:id,
master_only_md5:sendOutId
},function(data){
var obj = eval(data);
if(obj.code == 90000){
getNewMsgUser(id);
}else if(obj.entity == 0){
$("#"+id).html(parseInt($("#"+id).html())+1);
//页面执行了+1功能,
//数据库里要存放该数据,如果管理端进行了页面刷新,需要获取数据库里未读数据填充到页面上
}else{
var htmls = "<div class=\"leftd\">"+
"<div style=\"float:left;\">"+
"<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
"</div>"+
"<div class=\"speech left\" style=\"margin-left:61px;\">"+message.content.content+"</div>"+
"</div>";
$("#liaotian").append(htmls);
}
$('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
});
}
}
});
该监听功能里面文字已经描述的很详细了
主要涉及到:未读消息数量。是否新用户来跟客服聊天
涉及到新用户跟客服聊天使用到的js
主要是创建新头像。但是目前本地并没有获取新用户的信息。暂时使用的是假数据,除了ID是真是的。
不过用户信息获取很简单。
//当新用户跟管理员聊天时,则新增头像,
//需要后端获取用户信息传到该方法里,替换掉默认的头像和昵称
function getNewMsgUser(userId){
var htmls = "<div style=\"width:180px;height:60px;\" οnclick=\"pushUser('"+userId+"')\">"+
"<img alt=\"用户头像\" width=\"40px\" height=\"40px\" src=\"${ctx}/img/20180917141606.png\">"+
"<label>昵称</label>"+
" <label style=\"color:red;\" id=\""+userId+"\">1</label></div>";
$("#newMsgUser").append(htmls);
}
未读消息有了。那么就应该有清除未读消息:
当客服点击用户头像是,即进入跟用户聊天模式。
这里涉及到:清除该用户的未读消息,关联该客服与用户的再聊关系。
//获取跟该用户的历史聊天记录
function getHisMsgUser(users_only_md5){
//用来查看页面上是否存在未读消息数量
var count = $("#"+users_only_md5).html();
if(regNull(hisHtmls)){
$.get("${ctx}/webMessage/selectWebMessageUsers.htmls",
{
users_only_md5:users_only_md5,
master_only_md5:'${currUserId}',
readNum:count
},
function(data){
var obj = eval(data);
pushHTML(obj.entity,"users");
//该ajax已经将未读消息重置为0,jquery重置页面未读数量
$("#"+users_only_md5).html(0);
});
}
}
readNum:上一章没有该字段,此处用到是为了让java代码做一层判断。
如果未读消息数量 >1 则需要重置未读0.否则不需要进行update 代码。
还有就是,每次点击头像(不同的用户)1:获取跟该用户的历史聊天记录,2:关联跟该用户的再聊状态,取消之前的再聊状态。
关于 用户与管理员再聊关系,这边还有一个隐藏bug:一个用户和多个客服聊天怎么办?
1:定义死:即用户app端只能跟一个客服聊天,系统分配的客服。
2:灵活性:当前用户跟客服1聊天,如果当前用户需要重新分配客服,则取消和客服1的聊天状态,重新创建新的关系,
但其中的聊天记录,则在分配新的客服时,将新客服id关联到那个历史聊天记录表里。目前本地还没有实现。
到此,聊天功能已经完成一大半了。或者说,在优化代码逻辑之前。应该算是接近尾声了。
下一章还需要写用户管理员在线不在线功能。
备注:第一章和第二章需要连起来看,毕竟代码有重复,但是代码内容有修改,第二章为新代码。
代码下载路径:
我发布的时候,都不给我选择免费,默认积分1下载。头疼。。。。。。。
还有该代码下载部署到开发工具中是无法运行了。因为链接了数据库,需要自行创建数据库,
字段参照 pojo类。
还有框架使用了maven配置。需要注意。