first commit

This commit is contained in:
Ray
2026-02-19 03:37:37 +08:00
commit ccfd8c79a4
2813 changed files with 453657 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

View File

@@ -0,0 +1,905 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="include/head.jsp"%>
<!-- ========== Css Files ========== -->
<link href="css/root.css" rel="stylesheet">
<style>
.panel-body-chat .mailbox-inbox .searchbutton {
right: 22px;
top: 23px;
padding-left: 10px;
padding-right: 10px;
cursor: pointer;
line-height: 32px;
border-radius: 0 999px 999px 0;
}
.panel-body-chat .mailbox-inbox .searchbutton:after{
content: '';
position: absolute;
top: 5px;
bottom: 5px;
left: 0;
width: 1px;
background-color: rgba(0, 0, 0, 0.5);
}
.panel-body-chat .mailbox-inbox .searchbutton:hover i{
color: rgba(0, 0, 0, 0.9);
}
.panel-body-chat .bigImg{overflow: auto;display: none;text-align: center;position: fixed;top: 40px;bottom: 0;left: 0;width: 100%;background-color: rgba(0,0,0,0.4);z-index: 1000;}
.panel-body-chat .bigImg img{width: 300px;margin-top: 30px;}
.panel-body-chat .unreadhide{display: none;}
.panel-body-chat .chat .conv .img{width: 40px;height: 40px;}
.panel-body-chat .item-li-on{background: #D5EAFF;}
.panel-body-chat .chat .conv{height: calc( 100% - 223px);overflow: auto;}
.panel-body-chat .chat .conv .ballon {
max-width: 80%;
word-break: break-all;
margin: 5px 0;
padding: 4px 20px
}
.panel-body-chat .chat .conv .date{border:0;padding: 0;}
.panel-body-chat .chat .conv li{margin: 0;}
.panel-body-chat .container-mailbox{
/* width: 1000px; */
height: 100%;
margin: 0 auto;
background-color: #fff;
overflow: hidden;
}
.panel-body-chat .mailbox-inbox .unread {
position: absolute;
font-size: 10px;
right: 20px;
bottom: 20px;
color: #fff;
background-color: #f00;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 30px;
}
.panel-body-chat .fixed-right-b{
position: fixed;
right: 60px;
bottom: 180px;
width: 50px;
height: 50px;
line-height: 50px;
background-color: #fff;
border-radius: 50px;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
text-align: center;
color: #999;
cursor: pointer;
}
.panel-body-chat .fixed-right-b i{
font-size: 50px;
font-weight: 600;
}
.panel-body-chat .un-num{
position: absolute;
top: -20px;
left: 10px;
width: 30px;
height: 30px;
line-height: 30px;
border-radius: 30px;
text-align: center;
background-color: #0066ff;
color: #fff;
font-size: 16px;
font-weight: 600;
}
.panel-body-chat .title h1{line-height: 55px;}
.panel-body-chat .img-show{width: 260px;cursor: pointer;}
.panel-body-chat .img-loading{width: 40px;}
.panel-body-chat .msg-list{width: 100%;height: calc( 100% - 85px);overflow: auto;}
.panel-body-chat .right-msg{text-align: right; padding-right: 70px; padding-left: 0px!important;}
.panel-body-chat .right-msg .img{right:0;left: unset!important;}
.panel-body-chat .mailbox .write{padding: 0 20px;}
.panel-body-chat .mailbox,.panel-body-chat .padding-0,.panel-body-chat .mailbox-inbox{height: 100%;}
/*滚动条样式*/
.panel-body-chat .conv::-webkit-scrollbar {width: 4px;}
.panel-body-chat .conv::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.panel-body-chat .conv::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.panel-body-chat .msg-list::-webkit-scrollbar {width: 4px;}
.panel-body-chat .msg-list::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.panel-body-chat .msg-list::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.write{position: relative;}
.photo-add {
position: absolute;
right: 30px;
top: 5px;
width: 30px;
height: 30px;
cursor: pointer;
}
.item-image {
display: block;
width: 100%;
/* height: 100%; */
}
.uploader-file {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
z-index:-1;
}
</style>
</head>
<body>
<%@ include file="include/loading.jsp"%>
<%@ include file="include/alert.jsp"%>
<input type="hidden" value="" id="partyid" />
<input type="hidden" value="1" id="pageno" />
<input type="hidden" value="" id="message_id" />
<input type="hidden" value="0" id="isScroll" /><!-- 是否滚动底部 0到底/1没到底 -->
<input type="hidden" value="1" id="hasmore" /><!-- 是否有上一页 0无/1有 -->
<!-- Start Page Loading -->
<div class="loading"><img src="<%=basePath%>img/chat/loading.gif" alt="loading-img"></div>
<!-- End Page Loading -->
<!-- Start Page BigImg -->
<div class="bigImg"><img src="" alt="img"></div>
<!-- End Page BigImg -->
<!-- Start Mailbox -->
<div class="mailbox clearfix">
<!-- Start Mailbox Container -->
<div class="container-mailbox">
<!-- Start Mailbox Inbox -->
<div class="col-md-3 col-sm-3 col-xs-3 padding-0">
<ul class="mailbox-inbox">
<li class="search">
<form>
<input type="text" class="mailbox-search" id="mailboxsearch" placeholder="Search">
<span onclick="searchMsg()" class="searchbutton"><i class="fa fa-search"></i></span>
</form>
</li>
<!-- 消息列表 -->
<div class="msg-list">
</div>
</ul>
</div>
<!-- End Mailbox Inbox -->
<!-- Start Chat -->
<div class="chat col-md-9 col-sm-9 col-xs-9 padding-0">
<!-- Start Title -->
<div class="title">
<h1></h1>
<!-- <h1>Index Design and Some Advice <small>( mail@jonathandoe.com )</small></h1> -->
<!-- <p><b>To:</b> Me</p> -->
<div class="btn-group" role="group" aria-label="..." style="right:40px;">
<!-- <button type="button" class="btn btn-icon btn-sm btn-light"><i class="fa fa-share"></i></button> -->
<!-- <button type="button" class="btn btn-icon btn-sm btn-light"><i class="fa fa-star-o"></i></button> -->
<button onclick="deleteUser()" type="button" class="btn btn-icon btn-sm btn-light"><i class="fa fa-trash"></i></button>
</div>
</div>
<!-- End Title -->
<!-- Start Conv -->
<ul class="conv">
</ul>
<!-- End Conv -->
<div class="write">
<div class="photo-add">
<img class="item-image" src="<%=basePath%>img/chat/icon-add-old.png" alt="">
<input type="file" accept="image/*"
name="uploader-input"
class="uploader-file"
id="upload">
</div>
<div class="">
<p><textarea id="send-textarea" class="textarea form-control" placeholder="ctrl+enter发送消息"
style="height:100px; width:100%;"></textarea></p>
<button onclick="sendMsg('text')" style="float: right;" class="btn btn-default margin-l-5">发送</button>
<button onclick="clearSendWord()" style="float: right;" type="reset" class="btn">清空</button>
</div>
</div>
</div>
<!-- End Chat -->
</div>
<!-- End Mailbox Container -->
</div>
<!-- End Mailbox -->
<div class="fixed-right-b" onclick="goBottom()">
<!-- <div class="un-num">0</div> -->
<i class="fa fa-angle-down"></i>
</div>
<%-- <%@ include file="include/js.jsp"%> --%>
<script type="text/javascript" src="<%=basePath%>js/jquery.min.js"></script>
<%-- <script src="<%=basePath%>js/bootstrap/bootstrap.min.js"></script> --%>
<%-- <script type="text/javascript" src="<%=basePath%>js/plugins.js"></script> --%>
<script>
var chatHeight = $(".conv").height() + 40;
$(window).resize(function() {
chatHeight = $(".conv").height() + 40;
});
var setInt = null;//定时器
// 用户列表
function getMsgList(partyid) {
$.ajax({
type: 'GET',
data: {
},
url: "<%=basePath%>normal/adminOnlineChatAction!userlist.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
var msgList = res.data;
var msgContent = '';
if(msgList.length>0){
if($("#pageno").val()==1){
if(!$(".title h1").html()){
$(".title h1").html(msgList[0].username);
}
if(!$("#partyid").val()){
$("#partyid").val(msgList[0].partyid);
getMsgDetailList(msgList[0].partyid,false);
getMsgDetailList(msgList[0].partyid,true);
}
}
}else{
$(".title h1").html('');
$(".mailbox-inbox .msg-list").html('');
$(".conv").html('');
$("#partyid").val("");
return
}
var liLen = $(".mailbox-inbox .msg-list li").length;
if(liLen==0){
for (var i = 0; i < msgList.length; i++) {
msgContent += '<li class="item-li '
+ msgList[i].username +'" partyid="'
+ msgList[i].partyid +'"><a href="#" class="item clearfix"><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><span class="from">'
+ msgList[i].username + '</span><span class="chat_content">'
+ msgList[i].content + '</span><span class="date">'
+ msgList[i].updatetime + '</span>';
if(msgList[i].unreadmsg){
msgContent += '<span class="unread">'
+ msgList[i].unreadmsg + '</span>'
}else{
msgContent += '<span class="unread unreadhide">'
+ msgList[i].unreadmsg + '</span>';
}
msgContent += '</a></li>'
}
$(".mailbox-inbox .msg-list").html(msgContent);
}else{
var tiLi = '';
var jianNum = Math.abs(liLen - msgList.length);
for (var i = 0; i < jianNum; i++){
if(msgList.length<liLen){
//减
$(".mailbox-inbox .msg-list li:last-child").remove();
}else{
//加
var msgContent = '<li class="item-li '
+ msgList[i].username +'" partyid="'
+ msgList[i].partyid +'"><a href="#" class="item clearfix"><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><span class="from">'
+ msgList[i].username + '</span><span class="chat_content">'
+ msgList[i].content + '</span><span class="date">'
+ msgList[i].updatetime + '</span>';
if(msgList[i].unreadmsg){
msgContent += '<span class="unread">'
+ msgList[i].unreadmsg + '</span>';
}else{
msgContent += '<span class="unread unreadhide">'
+ msgList[i].unreadmsg + '</span>';
}
msgContent += '</a></li>'
$(".mailbox-inbox .msg-list").append(msgContent);
}
}
for (var i = 0; i < msgList.length; i++) {
if(msgList[i].unreadmsg){
$(".mailbox-inbox .msg-list li").eq(i).find(".unread").html(msgList[i].unreadmsg);
$(".mailbox-inbox .msg-list li").eq(i).find(".unread").removeClass("unreadhide");
}else{
$(".mailbox-inbox .msg-list li").eq(i).find(".unread").addClass("unreadhide");
}
$(".mailbox-inbox .msg-list li").eq(i).find(".from").html(msgList[i].username);
$(".mailbox-inbox .msg-list li").eq(i).find(".chat_content").html(msgList[i].content);
$(".mailbox-inbox .msg-list li").eq(i).find(".date").html(msgList[i].updatetime);
var newClass = "item-li "+msgList[i].username
$(".mailbox-inbox .msg-list li").eq(i).attr("class", newClass);
$(".mailbox-inbox .msg-list li").eq(i).attr("partyid", msgList[i].partyid);
}
}
var onClass = "."+$(".title h1").html();
$(".item-li").removeClass("item-li-on");
$(onClass).addClass("item-li-on");
if(partyid){
var offetTop = $(".msg-list li[partyid="+partyid+"]").offset().top-120;
$(".msg-list").animate({
scrollTop: offetTop
}, 500);
$(".msg-list li[partyid="+partyid+"]").click();
}
}
},
error: function(err) {}
})
}
getMsgList();
//创建新用户消息列表
function searchMsg() {
var username = $("#mailboxsearch").val();
$.ajax({
type: 'GET',
data: {
uid: username
},
url: "<%=basePath%>normal/adminOnlineChatAction!create.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
getMsgList(res.data);
}else if (res.code == 1) {
swal({title:res.msg,timer:2000});
}
$("#mailboxsearch").val('');
},
error: function(err) {}
})
}
// 聊天记录列表
function getMsgDetailList(partyid,show_img) {
$.ajax({
type: 'GET',
data: {
message_id: '',
partyid: partyid,
show_img: show_img
},
url: "<%=basePath%>normal/adminOnlineChatAction!list.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
if(show_img){
var msgDetailList = res.data;
for (var i = 0; i < msgDetailList.length; i++) {
var classId = "." + msgDetailList[i].id;
if($(classId).hasClass("img-show")){
$(classId).attr('src',msgDetailList[i].content);
$(classId).removeClass("img-loading");
}
}
}else{
var msgDetailList = res.data.reverse();
var msgDetailContent = '';
if(msgDetailList.length>0){
$("#message_id").val(msgDetailList[0].id);
}
for (var i = 0; i < msgDetailList.length; i++) {
var divid = "#" + msgDetailList[i].id;
if($(divid).html()){continue}
// if ('时间') {
msgDetailContent += '<div id="'
+ msgDetailList[i].id + '"><li class="date">'
+ msgDetailList[i].createtime + '</li>'
// }
if (msgDetailList[i].send_receive == 'receive') {
if (msgDetailList[i].type == 'img') {
if(msgDetailList[i].content){//如果图片存在就显示图片
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><br><img src="'
+ msgDetailList[i].content +'" alt="img" class="img-show '
+ msgDetailList[i].id +'"></li></div>'
}else{//如果图片不存在就显示加载中图片
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><br><img src="'
+ '<%=basePath%>img/chat/loadin<%=basePath%>img/chat/f' +'" alt="img" class="img-show img-loading '
+ msgDetailList[i].id +'"></li></div>'
}
}else{
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><p class="ballon color1">'
+ msgDetailList[i].content + '</p></li></div>'
}
} else if (msgDetailList[i].send_receive == 'send') {
if (msgDetailList[i].type == 'img') {
if(msgDetailList[i].content){
msgDetailContent += '<li><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><br><img src="'
+ msgDetailList[i].content +'" alt="img" class="img-show '
+ msgDetailList[i].id +'"></li></div>'
}else{
msgDetailContent += '<li><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><br><img src="'
+ '<%=basePath%>img/chat/loading.gif' +'" alt="img" class="img-show img-loading '
+ msgDetailList[i].id +'"></li></div>'
}
}else{
msgDetailContent += '<li><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><p class="ballon color2">'
+ msgDetailList[i].content + '</p></li></div>'
}
}
$(".conv").append(msgDetailContent);
msgDetailContent = ''
}
}
}
},
error: function(err) {}
})
}
// 定时检查是否需要滚动条置底操作
setInterval(function(){
var scrollHeight = $(".conv")[0].scrollHeight
if($("#isScroll").val()!=1){
$(".fixed-right-b").hide();
$(".conv").animate({
scrollTop: scrollHeight
}, 500);
}else{
$(".fixed-right-b").show();
}
},700)
var timeout;//用于存储定时器的变量
//鼠标点击事件,用户判断是否用鼠标拖动滚动条
$(".conv").mousedown(function(e) {
timeout= setTimeout(function() {
$(".conv").scroll(function() {
$("#isScroll").val(1);
var scroH = $(".conv").scrollTop(); //滚动高度
var scrollHeight = $(".conv")[0].scrollHeight
scroH = Math.ceil(scroH);
chatHeight = $(".conv").height() + 40;
if (scroH+chatHeight>=scrollHeight){ //滚动条滑到底部啦
$("#isScroll").val(0);
} else{
$("#isScroll").val(1);
}
})
}, 200);//鼠标按下0.2秒后发生事件
});
$(document).mouseup(function() {
clearTimeout(timeout);//清理掉定时器
});
$(document).mouseout(function() {
clearTimeout(timeout);//清理掉定时器
});
// 鼠标滚动事件
$(document).on("mousewheel DOMMouseScroll", function (e) {
chatHeight = $(".conv").height() + 40;
$("#isScroll").val(1);
var scroH = $(".conv").scrollTop(); //滚动高度
var scrollHeight = $(".conv")[0].scrollHeight
scroH = Math.ceil(scroH);
var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
(e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1)); // firefox
if (delta > 0) {
// 向上滚
if(scroH<200&&scrollHeight>chatHeight){
var page_no = $("#pageno").val();
page_no ++;
$("#pageno").val(page_no);
if($("#hasmore").val() == 1){
getMsgDetailMoreList($("#partyid").val(),false);
getMsgDetailMoreList($("#partyid").val(),true);
}
}
} else if (delta < 0) {
// 向下滚
if (scroH+chatHeight+100>=scrollHeight){ //滚动条滑到底部啦
$("#isScroll").val(0);
} else{
$("#isScroll").val(1);
}
}
});
// 上一页消息内容列表
function getMsgDetailMoreList(partyid,show_img) {
$.ajax({
type: 'GET',
data: {
message_id: $("#message_id").val(),
partyid: partyid,
show_img: show_img
},
url: "<%=basePath%>normal/adminOnlineChatAction!list.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
if(show_img){
var msgDetailList = res.data;
for (var i = 0; i < msgDetailList.length; i++) {
var classId = "." + msgDetailList[i].id;
if($(classId).hasClass("img-show")){
$(classId).attr('src',msgDetailList[i].content);
$(classId).removeClass("img-loading");
}
}
}else{
var msgDetailList = res.data.reverse();
var msgDetailContent = '';
if(msgDetailList.length==0){
$("#hasmore").val(0);
return
}
$("#message_id").val(msgDetailList[0].id);
for (var i = 0; i < msgDetailList.length; i++) {
var divid = "#" + msgDetailList[i].id;
if($(divid).html()){continue}
// if ('时间') {
msgDetailContent += '<div id="'
+ msgDetailList[i].id + '"><li class="date">'
+ msgDetailList[i].createtime + '</li>'
// }
if (msgDetailList[i].send_receive == 'receive') {
if (msgDetailList[i].type == 'img') {
if(msgDetailList[i].content){
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><br><img src="'
+ msgDetailList[i].content +'" alt="img" class="img-show '
+ msgDetailList[i].id +'"></li></div>'
}else{
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><br><img src="'
+ '<%=basePath%>img/chat/loading.gif' +'" alt="img" class="img-show img-loading '
+ msgDetailList[i].id +'"></li></div>'
}
}else{
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><p class="ballon color1">'
+ msgDetailList[i].content + '</p></li></div>'
}
} else if (msgDetailList[i].send_receive == 'send') {
if (msgDetailList[i].type == 'img') {
if(msgDetailList[i].content){
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><br><img src="'
+ msgDetailList[i].content +'" alt="img" class="img-show '
+ msgDetailList[i].id +'"></li></div>'
}else{
msgDetailContent += '<li class="right-msg"><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><br><img src="'
+ '<%=basePath%>img/chat/loading.gif' +'" alt="img" class="img-show img-loading '
+ msgDetailList[i].id +'"></li></div>'
}
}else{
msgDetailContent += '<li><img src="'
+'<%=basePath%>img/chat/my-ico2.png' + '" alt="img" class="img"><p class="ballon color2">'
+ msgDetailList[i].content + '</p></li></div>'
}
}
$(".conv").prepend(msgDetailContent);
msgDetailContent = '';
}
// $(".conv>li").eq(0).before(msgDetailContent);
}
}
},
error: function(err) {}
})
}
// 图片点击事件
$(".conv").on("click","img",function(){
var imgUrl = $(this).attr("src");
// $(".bigImg").show();
// $(".bigImg img").attr("src", imgUrl);
var newwin=window.open()
var height="height:"+window.screen.height+";";
var width="width:"+window.screen.width+";";
// var height="height:"+window.screen.availHeight+";";
// var width="width:"+window.screen.availWidth+";";
newwin.document.write("<div style='display: table-cell;text-align: center;vertical-align: middle;background: #0e0e0e;"+height+width+"'><img src="+imgUrl+" /></div>")
})
$(".bigImg").click(function(){
$(".bigImg").hide();
})
$(".msg-list").on("click",".item-li",function(){
// 更改用户聊天记录时,清除定时器
clearInterval(setInt);
setInt = null;
$("#isScroll").val(0);
$("#pageno").val(1);
$(".conv").html('');
var partyid = $(this).attr("partyid");
$("#partyid").val(partyid);
$(".title h1").html($(this).find(".from").html());
$(".item-li").removeClass("item-li-on");
$(this).addClass("item-li-on");
// 重新打开定时器,定时刷新用户列表与聊天记录
setInt = setInterval(function(){
getMsgList();
if($("#partyid").val()&&$("#isScroll").val()==0){
//聊天记录在第一页 滚动条在底部 当前有聊天时,刷新聊天记录
getMsgDetailList($("#partyid").val(),false)
getMsgDetailList($("#partyid").val(),true)
}
},1000)
getMsgDetailList(partyid,false);
getMsgDetailList(partyid,true);
})
// 定时刷新用户列表与聊天记录
setInt = setInterval(function(){
getMsgList();
if($("#partyid").val()&&$("#isScroll").val()==0){
//聊天记录在第一页 滚动条在底部 当前有聊天时,刷新聊天记录
getMsgDetailList($("#partyid").val(),false)
getMsgDetailList($("#partyid").val(),true)
}
},1000)
$(document).keypress(function (e){
var stat = false;
if(e.keyCode == 10){
sendMsg("text");
}
})
// 发送消息
function sendMsg(type) {
$("#isScroll").val(0)
$.ajax({
type: 'POST',
data: {
type: type,
content: $("#send-textarea").val(),
partyid: $("#partyid").val()
},
url: "<%=basePath%>normal/adminOnlineChatAction!send.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
getMsgDetailList($("#partyid").val(),false);
getMsgDetailList($("#partyid").val(),true);
$("#send-textarea").val('');
$("#send-textarea").focus();
}else if (res.code == 1) {
swal(res.msg);
}
},
error: function(err) {}
})
}
function goBottom(){
// 滚动到底部
var scrollHeight = $(".conv")[0].scrollHeight
$(".conv").animate({
scrollTop: scrollHeight
}, 500);
getMsgDetailList($("#partyid").val(),false)
getMsgDetailList($("#partyid").val(),true)
$("#isScroll").val(0)
}
// 清除输入框文字
function clearSendWord() {
$("#send-textarea").val('');
}
// 删除聊天
function deleteUser(){
swal({
title : "是否确认删除?",
text : "",
type : "warning",
showCancelButton : true,
confirmButtonColor : "#DD6B55",
confirmButtonText : "确认",
cancelButtonText: "取消",
// closeOnConfirm : false
}, function(isConfirm){
if (isConfirm) {
$.ajax({
type: 'GET',
data: {
partyid: $("#partyid").val()
},
url: "<%=basePath%>normal/adminOnlineChatAction!del.action",
success: function(data) {
var res = $.parseJSON(data);
if (res.code == 0) {
swal("已删除!");
$("#partyid").val('');
$(".title h1").html('');
clearInterval(setInt);
setInt = null;
getMsgList();
}
},
error: function(err) {}
})
}
});
}
// 图片上传
$(".photo-add").click(function(){
$('#upload').click();
})
$('#upload').on('change', function (event) {
var $file = event.currentTarget;
var formData = new FormData();
var file = $file.files[0];
console.log(file,"file")
if(!file){return}
var loadingImg = '<li class="right-msg" id="loadingimg"><img src="'
+'<%=basePath%>img/chat/my-ico.png' + '" alt="img" class="img"><br><img src="'
+ '<%=basePath%>img/chat/loading.gif' +'" alt="img" class="img-show img-loading"></li>'
$(".conv").append(loadingImg);
goBottom();
if (!/image\/\w+/.test(file.type)) {
alert("只能选择图片");
return false;
}
if(file.size<102400){
sendFile(file);
return
}
var reader = new FileReader();
reader.onloadend = function () {
// 创建对象
var imgUp = new Image();
// 改变图片的src
imgUp.src = reader.result;
imgUp.onload = function(){
let canvasWidth = imgUp.width //图片原始长宽
let canvasHeight = imgUp.height
/* let img = new Image() */
/* imgUp.src = res.path */
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d')
canvas.width = 500
var rateImg = 500*canvasHeight/canvasWidth;
canvas.height = rateImg
// canvas.width = canvasWidth*0.6
// canvas.height = canvasHeight*0.6
ctx.drawImage(imgUp, 0, 0, canvas.width, canvas.height)
canvas.toBlob(function(fileSrc) {
sendFile(fileSrc);
})
};
}
if (file) {
reader.readAsDataURL(file);
}
});
function sendFile(file){
var formData = new FormData();
formData.append("file",file);
/* formData.append("content",reader.result); */
formData.append("partyid",$("#partyid").val());
formData.append("type","img");
$.ajax({
url: "<%=basePath%>normal/adminOnlineChatAction!send.action",
dataType:'json',
type:'POST',
async: false,
data: formData,
processData : false, // 使数据不做处理
contentType : false, // 不要设置Content-Type请求头
success: function(data){
var res = $.parseJSON(data);
if (res.code == 0) {
getMsgDetailList($("#partyid").val(),false);
getMsgDetailList($("#partyid").val(),true);
// $(".item-image").attr("src", "<%=basePath%>img/chat/icon-add-old.png");
}else if (res.code == 1) {
swal(res.msg);
}
$("#loadingimg").remove();
$('#upload').val("");
},
error:function(response){
$("#loadingimg").remove();
$('#upload').val("");
// console.log(response);
}
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
\
<dubbo:reference id="onlineChatMessageService"
interface="project.onlinechat.OnlineChatMessageService" check="false" />

View File

@@ -0,0 +1,3 @@
api
<!--onlineChat -->
<value>onlineChatMessageService</value>

View File

@@ -0,0 +1,12 @@
admin
<action name="adminOnlineChatAction"
class="project.onlinechat.web.AdminOnlineChatAction">
<result name="result_make" type="json">
<param name="root">result_make</param>
</result>
</action>
api
<action name="onlinechat"
class="project.onlinechat.web.OnlineChatAction">
</action>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<bean id="onlineChatMessageService"
class="project.onlinechat.internal.OnlineChatMessageServiceImpl" init-method="init" >
<property name="hibernateTemplate" ref="hibernateTemplate" />
<property name="partyService" ref="partyService" />
</bean>
<dubbo:service
interface="project.onlinechat.OnlineChatMessageService"
ref="onlineChatMessageService" />
</beans>

View File

@@ -0,0 +1,69 @@
DROP TABLE IF EXISTS `T_ONLINECHAT_MESSAGE`;
CREATE TABLE `T_ONLINECHAT_MESSAGE` (
`UUID` varchar(32) NOT NULL,
`PARTY_ID` varchar(32) NOT NULL,
`SEND_RECEIVE` varchar(32) NOT NULL,
`CONTENT_TYPE` varchar(32) NOT NULL,
`CONTENT` longtext,
`CREATE_TIME` datetime NOT NULL,
PRIMARY KEY (`UUID`),
KEY `INDEX_ONLINECHAT_MESSAGE_CREATE_TIME` (`CREATE_TIME`),
KEY `INDEX_PARTY_ID` (`PARTY_ID`),
KEY `INDEX_SEND_RECEIVE` (`SEND_RECEIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `T_MESSAGE_USER`;
CREATE TABLE `T_MESSAGE_USER` (
`UUID` varchar(32) NOT NULL,
`PARTY_ID` varchar(32) NOT NULL,
`TOTAL_MSG` int(11) NOT NULL DEFAULT '0',
`USER_UNREADMSG` int(11) NOT NULL,
`CUSTOMER_UNREADMSG` int(11) DEFAULT '0',
`UPDATETIME` datetime NOT NULL,
`DELETE_STATUS` int(11) DEFAULT '0',
PRIMARY KEY (`UUID`),
KEY `INDEX_PARTY_ID` (`PARTY_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `T_OTC_MESSAGE_USER`;
CREATE TABLE `T_OTC_MESSAGE_USER` (
`UUID` varchar(32) NOT NULL,
`PARTY_ID` varchar(32) DEFAULT NULL,
`TOTAL_MSG` int(11) NOT NULL DEFAULT '0',
`USER_UNREADMSG` int(11) NOT NULL,
`CUSTOMER_UNREADMSG` int(11) DEFAULT '0',
`UPDATETIME` datetime NOT NULL,
`DELETE_STATUS` int(11) DEFAULT '0',
`REMARKS` varchar(255) DEFAULT NULL,
`IP` varchar(255) DEFAULT NULL,
`ORDER_NO` varchar(64) DEFAULT NULL,
PRIMARY KEY (`UUID`),
KEY `INDEX_PARTY_ID` (`PARTY_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `T_OTC_ONLINECHAT_MESSAGE`;
CREATE TABLE `T_OTC_ONLINECHAT_MESSAGE` (
`UUID` varchar(32) NOT NULL,
`PARTY_ID` varchar(32) DEFAULT NULL,
`SEND_RECEIVE` varchar(32) NOT NULL,
`CONTENT_TYPE` varchar(32) NOT NULL,
`CONTENT` longtext,
`CREATE_TIME` datetime NOT NULL,
`USERNAME` varchar(255) DEFAULT NULL,
`IP` varchar(255) DEFAULT NULL,
`ORDER_NO` varchar(64) DEFAULT NULL,
PRIMARY KEY (`UUID`),
KEY `INDEX_ONLINECHAT_MESSAGE_CREATE_TIME` (`CREATE_TIME`),
KEY `INDEX_PARTY_ID` (`PARTY_ID`),
KEY `INDEX_SEND_RECEIVE` (`SEND_RECEIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `T_ONLINECHAT_MESSAGE`
ADD COLUMN `USERNAME` varchar(255) ;
ALTER TABLE `T_MESSAGE_USER`
ADD COLUMN `REMARKS` varchar(255) ;
ALTER TABLE `T_MESSAGE_USER`
ADD COLUMN `TARGET_USERNAME` varchar(64) NULL AFTER `IP`;

View File

@@ -0,0 +1,129 @@
package project.onlinechat;
import kernel.bo.EntityObject;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
public class ChatUser extends EntityObject implements Comparable<ChatUser> {
private static final long serialVersionUID = 6632900428820490181L;
/**
* 会话id 生成规则为对话的用户id组合而成 若为游客则为ip地址
*/
private String chat_id;
/**
* 发起会话用户id 2023-06-15新增需求将此处id固定位 买家id
*/
private String start_id;
/**
* 用户id 2023-06-15 新增需求将此处id固定位 商家id
*/
private String user_id;
/**
* 发起会话用户未读数
*/
private int start_unread;
/**
* 客服未读
*/
private int user_unread;
/**
* 商家接收到的买家未被审核消息的未读数字
*/
private int unAuditUnread;
private Date updateTime;
/**
* 标记删除,-1:删除0:正常
*/
private int delete_status;
/**
* 备注
*/
private String remarks;
@Override
public int compareTo(@NotNull ChatUser chatUser) {
if (this.updateTime.after(chatUser.getUpdateTime())) {
return -1;
} else if (this.updateTime.before(chatUser.getUpdateTime())) {
return 1;
}
return 0;
}
public int getUnAuditUnread() {
return unAuditUnread;
}
public void setUnAuditUnread(int unAuditUnread) {
this.unAuditUnread = unAuditUnread;
}
public String getChat_id() {
return chat_id;
}
public void setChat_id(String chat_id) {
this.chat_id = chat_id;
}
public String getStart_id() {
return start_id;
}
public void setStart_id(String start_id) {
this.start_id = start_id;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public int getStart_unread() {
return start_unread;
}
public void setStart_unread(int start_unread) {
this.start_unread = start_unread;
}
public int getUser_unread() {
return user_unread;
}
public void setUser_unread(int user_unread) {
this.user_unread = user_unread;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public int getDelete_status() {
return delete_status;
}
public void setDelete_status(int delete_status) {
this.delete_status = delete_status;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
}

View File

@@ -0,0 +1,112 @@
package project.onlinechat;
import java.util.Date;
import kernel.bo.EntityObject;
import redis.clients.util.Pool;
public class MessageUser extends EntityObject implements Comparable<MessageUser> {
private static final long serialVersionUID = -7768174302895619763L;
private String partyId;
/**
* 用户未读
*/
private int user_unreadmsg;
/**
* 客服未读
*/
private int customer_unreadmsg;
private Date updateTime;
/**
* 标记删除,-1:删除0:正常
*/
private int delete_status;
/**
* 备注
*/
private String remarks;
private String ip;
/**
* 发给指定用户
*/
private String target_username;
public String getPartyId() {
return partyId;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public void setPartyId(String partyId) {
this.partyId = partyId;
}
@Override
public int compareTo(MessageUser messageUser) {
if (this.updateTime.after(messageUser.getUpdateTime())) {
return -1;
} else if (this.updateTime.before(messageUser.getUpdateTime())) {
return 1;
}
return 0;
}
public int getUser_unreadmsg() {
return user_unreadmsg;
}
public int getCustomer_unreadmsg() {
return customer_unreadmsg;
}
public void setUser_unreadmsg(int user_unreadmsg) {
this.user_unreadmsg = user_unreadmsg;
}
public void setCustomer_unreadmsg(int customer_unreadmsg) {
this.customer_unreadmsg = customer_unreadmsg;
}
public int getDelete_status() {
return delete_status;
}
public void setDelete_status(int delete_status) {
this.delete_status = delete_status;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getTarget_username() {
return target_username;
}
public void setTarget_username(String target_username) {
this.target_username = target_username;
}
}

View File

@@ -0,0 +1,126 @@
package project.onlinechat;
import java.util.Date;
import kernel.bo.EntityObject;
/**
* 客服留言表
*
*/
public class OnlineChatMessage extends EntityObject implements Comparable<OnlineChatMessage> {
private static final long serialVersionUID = -4999012202564084751L;
private String partyId;// varchar(32),
/**
* send 发送 receive 接收
*/
private String send_receive;// 1 用户发送 2 用户接收
/**
* text img
*/
private String type;
private String content;// 留言内容
private Date createTime;
private String username;// 用户名(管理员发送时纪录)
private String target_username;// 发送到指定用户
private String ip;
/**
* 标记删除,-1:删除0:正常
*/
private int delete_status=0;
public String getPartyId() {
return partyId;
}
public void setPartyId(String partyId) {
this.partyId = partyId;
}
public String getSend_receive() {
return send_receive;
}
public void setSend_receive(String send_receive) {
this.send_receive = send_receive;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public int compareTo(OnlineChatMessage onlineChatMessage) {
if (this.createTime.after(onlineChatMessage.getCreateTime())) {
return 1;
} else if (this.createTime.before(onlineChatMessage.getCreateTime())) {
return -1;
}
return 0;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getTarget_username() {
return target_username;
}
public void setTarget_username(String target_username) {
this.target_username = target_username;
}
public int getDelete_status() {
return delete_status;
}
public void setDelete_status(int delete_status) {
this.delete_status = delete_status;
}
}

View File

@@ -0,0 +1,139 @@
package project.onlinechat;
import kernel.web.Page;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 客服中心管理
*/
public interface OnlineChatMessageService {
// public List<OnlineChatMessage> cacheGetList(int pageNo, int pageSize, String partyId);
/**
* 分页读取在线客服用户列表(管理员界面)
*/
public List<MessageUser> cacheGetMessageUserPage(int pageNo, int pageSize, String username);
public OnlineChatMessage saveSend(String partyId, String type, String send_receive, String content,
String username);
/*
* 创建一个对话,如果已经存在则将对话更新到首位
*/
public MessageUser saveCreate(String uid, String username);
public void delete(String partyId);
/**
* 未读消息数,不输入参数,则返回所有的未读消息数
*
* @param partyId
* @param type user:用户未读数customer:客服未读数
* @param targetUsername 当为客服时,指定用户的未读数
* @return
*/
public int getUnreadMsg(String partyId, String type, String targetUsername);
/**
* 更新未读数
*
* @param partyId
* @param user_customer 更新对象,用户,客服
* @param type read:读write
*/
public void updateUnread(String partyId, String user_customer, String type);
/**
* 根据消息id为起始索引获取翻页数据
*
* @param messageId
* @param pageSize
* @param partyId
* @param clicentType 请求的客户端类型用户端user客服端 不传
* @return
*/
public List<OnlineChatMessage> cacheGetList(String messageId, int pageSize, String partyId, String... clicentType);
/**
* 获取聊天用户
*
* @param key
* @return
*/
public MessageUser cacheMessageUser(String key);
/**
* 设置备注
*
* @param partyId
* @param remarks
*/
public String updateResetRemarks(String partyId, String remarks) throws Exception;
/**
* 获取用户信息
*
* @param partyId
* @return
*/
public Map<String, Object> getUserInfo(String partyId);
public Map<String, List<OnlineChatMessage>> cacheMessageAll();
public Map<String, MessageUser> cacheMessageUserAll();
public void putMessage(String key, List<OnlineChatMessage> value);
public void putMessageUser(String key, MessageUser value);
public List<OnlineChatMessage> cacheMessage(String key);
public void updateMessageUserByIp(MessageUser messageUser);
public void deleteByIp(String ip);
/**
* 移除通知
*
* @param partyId
* @param removeTipNum
*/
public void removeTips(String partyId, int removeTipNum);
/**
* 未分配到客服的用户,分配客服
*
* @return
*/
public void updateNoAnwserUser(String username);
/**
* 用户发送客服获取
*
* @param partyId
* @param sendTime
* @param targetUsername
* @return
*/
public String userSendTarget(String partyId, Date sendTime, String targetUsername);
public OnlineChatMessage getMessageById(String messageId);
/**
* 后台客服撤回消息操作
*
* @param messageId
* @param targetUserName
*/
public void updateMessageDelete(String messageId, String targetUserName);
/**
* 后台平台客服聊天分页查询
*/
Page pagedQuery(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para, String roleName_para, String sellerName_para ,String targetUserNamePara_para);
}

View File

@@ -0,0 +1,105 @@
package project.onlinechat;
import kernel.bo.EntityObject;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
/**
* 非客服聊天记录表
*/
public class OnlineChatUserMessage extends EntityObject implements Comparable<OnlineChatUserMessage> {
private static final long serialVersionUID = 3355519867841512649L;
private String chatId;// 会话id
private String sendId;// 消息发送者的id
private int sendType;//发送类型 1买家发送0商家发送
private String contentType;//消息类型 text img
private String content;// 留言内容
private Date createTime;
private int delete_status = 0;//标记删除,-1:删除0:正常
private int auditStatus;//消息审核状态(-1审核不通过0未审核 1审核通过)当审核不通过或者未审核时,卖家端聊天记录不展示
@Override
public int compareTo(@NotNull OnlineChatUserMessage onlineChatUserMessage) {
if (this.createTime.after(onlineChatUserMessage.getCreateTime())) {
return 1;
} else if (this.createTime.before(onlineChatUserMessage.getCreateTime())) {
return -1;
}
return 0;
}
public String getChatId() {
return chatId;
}
public void setChatId(String chatId) {
this.chatId = chatId;
}
public String getSendId() {
return sendId;
}
public void setSendId(String sendId) {
this.sendId = sendId;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public int getDelete_status() {
return delete_status;
}
public void setDelete_status(int delete_status) {
this.delete_status = delete_status;
}
public int getAuditStatus() {
return auditStatus;
}
public void setAuditStatus(int auditStatus) {
this.auditStatus = auditStatus;
}
public int getSendType() {
return sendType;
}
public void setSendType(int sendType) {
this.sendType = sendType;
}
}

View File

@@ -0,0 +1,81 @@
package project.onlinechat;
import kernel.web.Page;
import java.util.List;
import java.util.Map;
/*
* 非客服聊天管理
* */
public interface OnlineChatUserMessageService {
/**
* 分页读取会话用户列表
*/
public List<ChatUser> cacheGetMessageUserPage(int pageNo, int pageSize, String userId,String currentLoginType);
/**
* 根据消息id为起始索引获取分页数据
* @param messageId
*/
public List<OnlineChatUserMessage> cacheGetList(String loginType,String messageId, int pageSize, String... chatId);
/**
* 根据俩个用户的partyId 来发送这个消息
*/
OnlineChatUserMessage saveSend(String partyId, String sellerId, String type, String send, String content,int messageDeleteType,String loginType);
/**
*
* @param currentUserId
* @param loginType 根据登录类型来查找未读数字
* @return
*/
int getUnreadMsg(String currentUserId, String loginType);
long getTotalCountMsg(String partyId);
Map<String, Object> getBuyUnreadCount(String loginPartyId);
void updateUnread(String currentUserPartyId, String beReadPartyId);
/**
* 获取聊天用户
*/
public ChatUser cacheChatUser(String key);
public ChatUser findChatUserById(String id);
public ChatUser saveCreate(String chatId);
/**
* 后台全部聊天分页查询
*/
Page pagedQuery(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para, String roleName_para,
String sellerName_para ,String partyId,String sellerCode, String sellerRoleName);
/**
* 后台审查消息记录分页查询
*/
Page pagedQueryAudit(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para,String chatAudit_para,String loginPartyId);
/*
* 根据chatid跟新chatUser
*/
public void updateChatUserByChatId(ChatUser chatUser);
OnlineChatUserMessage getLastImMessage(String senderId, String receiverId, boolean includeImg, Long optionLimitTime);
boolean checkChat(String currentUserPartyId,String sellerId);
/**
* 自动清除历史聊天记录
*/
void updateAutoClearChatHistory();
void addWhite(String partyId);
void addBlack(String partyId);
}

View File

@@ -0,0 +1,45 @@
package project.onlinechat;
import java.util.Map;
/**
* 客服中心管理
*/
public interface OnlineChatVisitorMessageService {
public OnlineChatMessage saveSend(String ip, String type, String send_receive, String content, String username);
/*
* 创建一个对话,如果已经存在则将对话更新到首位
*/
public MessageUser saveCreate(String ip,String username);
/**
* 更新未读数
*
* @param ip
* @param user_customer 更新对象,用户,客服
* @param type read:读write
*/
public void updateUnread(String ip, String user_customer, String type);
/**
* 设置备注
*
* @param ip
* @param remarks
*/
public String updateResetRemarks(String ip, String remarks) throws Exception;
/**
* 获取用户信息
*
* @param ip
* @return
*/
public Map<String, Object> getUserInfo(String ip);
}

View File

@@ -0,0 +1,89 @@
package project.onlinechat.event;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import project.log.MallLogRedisKeys;
import project.mall.seller.SellerService;
import project.mall.task.MallOrdersJob;
import project.onlinechat.OnlineChatUserMessage;
import project.onlinechat.OnlineChatUserMessageService;
import project.onlinechat.event.message.ImSendEvent;
import project.party.PartyService;
import project.party.model.Party;
import project.redis.RedisHandler;
import project.syspara.SysparaService;
import project.user.token.TokenService;
import javax.annotation.Resource;
public class NotifySellerImEventListener implements ApplicationListener<ImSendEvent> {
private Log logger = LogFactory.getLog(this.getClass());
//@Resource
private RedisHandler redisHandler;
//@Resource
private PartyService partyService;
// @Resource
// private SellerService sellerService;
// @Resource
// private OnlineChatUserMessageService onlineChatUserMessageService;
@Override
public void onApplicationEvent(ImSendEvent event) {
OnlineChatUserMessage imMessage = event.getImMessage();
// chatId = sendPartyId + "-" + receivePartyId;
String chatId = imMessage.getChatId();
String[] chatInfoArr = chatId.split("-");
String senderId = chatInfoArr[0];
String receiverId = chatInfoArr[1];
logger.info("收到发送IM消息事件, chatId:" + chatId);
try {
Party senderEntity = partyService.cachePartyBy(senderId, true);
if (senderEntity == null) {
return;
}
// 如果消息发送者是买家,就检查下等待通知队列中是否有事件,如果有,就跳过
// 如果消息发送者是卖家,则检查下等待通知队列中是否有事件,如果有,就删除该缓存
// zset 缓存 value 的拼接规则:{sellerId : buyerId}
String cacheValue = "";
if (senderEntity.getRoleType() == 0) {
// 买家
cacheValue = receiverId.trim() + ":" + senderId.trim();
Double sendTime = redisHandler.zscore(MallLogRedisKeys.SELLER_IM_REPLY_NOTIFY, cacheValue);
if (sendTime == null) {
long now = System.currentTimeMillis();
// 产生待通知元素
redisHandler.zadd(MallLogRedisKeys.SELLER_IM_REPLY_NOTIFY, now, cacheValue);
// 注意:是站在卖家的视角生成缓存
String hashField = receiverId.trim() + ":" + senderId.trim();
String hashValue = imMessage.getId().toString() + ":" + now;
redisHandler.put(MallLogRedisKeys.SELLER_IM_LAST_BUYER_MESSAGE, hashField, hashValue);
} else {
// 已有元素,则以最早的为准
}
} else {
// 卖家回复,则清理通知缓存
cacheValue = senderId.trim() + ":" + receiverId.trim();
String hashField = senderId.trim() + ":" + receiverId.trim();
redisHandler.zrem(MallLogRedisKeys.SELLER_IM_REPLY_NOTIFY, cacheValue);
redisHandler.remove(MallLogRedisKeys.SELLER_IM_LAST_BUYER_MESSAGE, hashField);
}
} catch (Exception e) {
logger.error("买家用户:" + senderId + " 向商家:" + receiverId + " 发送咨询消息,生成提醒消息时报错", e);
}
}
public void setRedisHandler(RedisHandler redisHandler) {
this.redisHandler = redisHandler;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
}

View File

@@ -0,0 +1,17 @@
package project.onlinechat.event.message;
import org.springframework.context.ApplicationEvent;
import project.onlinechat.OnlineChatUserMessage;
public class ImSendEvent extends ApplicationEvent {
private OnlineChatUserMessage imMessage;
public ImSendEvent(Object source, OnlineChatUserMessage message) {
super(source);
this.imMessage = message;
}
public OnlineChatUserMessage getImMessage() {
return this.imMessage;
}
}

View File

@@ -0,0 +1,664 @@
package project.onlinechat.internal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import kernel.web.Page;
import kernel.web.PagedQueryDao;
import org.apache.commons.collections.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.util.CollectionUtils;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.util.ThreadUtils;
import project.onlinechat.MessageUser;
import project.onlinechat.OnlineChatMessage;
import project.onlinechat.OnlineChatMessageService;
import project.party.PartyService;
import project.party.model.Party;
import project.party.model.UserRecom;
import project.party.recom.UserRecomService;
import project.tip.TipConstants;
import project.tip.TipService;
import project.tip.model.Tip;
import project.user.UserService;
import systemuser.CustomerService;
import systemuser.model.Customer;
public class OnlineChatMessageServiceImpl extends HibernateDaoSupport implements OnlineChatMessageService {
protected static final Object OnlineChatMessage = null;
private Logger log = LoggerFactory.getLogger(OnlineChatMessageServiceImpl.class);
private Map<String, List<OnlineChatMessage>> cahce_chat = new ConcurrentHashMap<String, List<OnlineChatMessage>>();
private Map<String, MessageUser> cahce_user = new ConcurrentHashMap<String, MessageUser>();
private PagedQueryDao pagedQueryDao;
private PartyService partyService;
private UserRecomService userRecomService;
private TipService tipService;
private CustomerService customerService;
private UserService userService;
/**
*
* @param messageId
* @param pageSize
* @param partyId
* @param clicentType 请求的客户端类型用户端user客服端 不传
* @return
*/
public List<OnlineChatMessage> cacheGetList(String messageId, int pageSize, String partyId, String... clicentType) {
List<OnlineChatMessage> cache = cahce_chat.get(partyId);
if (cache == null) {
return new LinkedList<OnlineChatMessage>();
}
List<OnlineChatMessage> result = new ArrayList<OnlineChatMessage>();
result.addAll(cache);
// if (clicentType.length != 0 && "user".equals(clicentType[0])) {
// // 过滤掉已撤回的消息
// org.apache.commons.collections.CollectionUtils.filter(result, new Predicate() {
// @Override
// public boolean evaluate(Object arg0) {
// // TODO Auto-generated method stub
// OnlineChatMessage msg = (OnlineChatMessage) arg0;
// return msg.getDelete_status() == 0;
// }
// });
// }
int start = cacheIndex(messageId, result);
// start = start == 0 ? start : start + 1;// 空消息则表示首页,消息索引的后一条为起始
int end = start + pageSize;
if (start >= result.size()) {// 起始数据大于总量,返回空
return new LinkedList<OnlineChatMessage>();
}
if (cache.size() <= end)
end = result.size();
List<OnlineChatMessage> list = result.subList(start, end>=result.size()?result.size():end);
return list;
}
/**
* 获取消息的索引
*
* @param messageId
* @param list
* @return
*/
private int cacheIndex(String messageId, List<OnlineChatMessage> list) {
if (StringUtils.isEmptyString(messageId))
return 0;
int index = -1;
for (int i = 0; i < list.size(); i++) {
OnlineChatMessage message = list.get(i);
if (messageId.equals(message.getId().toString())) {
index = i;
}
}
if (index == -1) {
throw new BusinessException("参数异常,消息获取失败");
}
return index + 1;
}
@Override
public List<MessageUser> cacheGetMessageUserPage(int pageNo, int pageSize, String username) {
List<MessageUser> list = new ArrayList<MessageUser>(cahce_user.values());
List<MessageUser> result = new ArrayList<MessageUser>();
for (MessageUser user : list) {
if (user.getDelete_status() == -1) {
// System.out.println("Delete_status:" + user.getIp());
continue;
}
// 没有指定客服,客服不匹配
if (StringUtils.isEmptyString(user.getTarget_username()) || !username.equals(user.getTarget_username())) {
// System.out.println("Target_username:" + user.getIp());
continue;
}
result.add(user);
}
Collections.sort(result);
return result;
// 只获取前50个用户有消息会实时变化不做翻页
// int start = 0;
// int end = start + pageSize;
//
// if (result.size() <= end)
// end = result.size();
//
// List<MessageUser> resultUser = new ArrayList<MessageUser>();
// resultUser.addAll(result);
// List<MessageUser> subList = resultUser.subList(start, end);
//
// return subList;
}
@Override
public OnlineChatMessage saveSend(String partyId, String type, String send_receive, String content,
String username) {
OnlineChatMessage onlineChatMessage = new OnlineChatMessage();
onlineChatMessage.setPartyId(partyId);
onlineChatMessage.setType(type);
onlineChatMessage.setSend_receive(send_receive);
onlineChatMessage.setContent(content);
onlineChatMessage.setCreateTime(new Date());
onlineChatMessage.setUsername(username);
this.getHibernateTemplate().save(onlineChatMessage);
List<OnlineChatMessage> list = cahce_chat.get(partyId);
if (list == null) {
list = new LinkedList<OnlineChatMessage>();
}
list.add(onlineChatMessage);
Collections.sort(list);
Collections.reverse(list);// 添加完后,时间倒叙排序加回
this.cahce_chat.put(partyId, list);
if (!cahce_user.containsKey(partyId)) {// 不存在则添加用户
saveCreateByPartyId(partyId);
}
switch (send_receive) {
case "receive":// 客服发送
updateUnread(partyId, "user", "write");
break;
case "send":// 用户发送
updateUnread(partyId, "customer", "write");
// tipService.saveTip(onlineChatMessage.getId().toString(), TipConstants.ONLINECHAT);
break;
}
return onlineChatMessage;
}
public String userSendTarget(String partyId, Date sendTime, String targetUsername) {
if (StringUtils.isNotEmpty(targetUsername)) {
Customer customer = customerService.cacheByUsername(targetUsername);
// 表示该用户被有客服权限的系统用户接手
if (customer == null) {
return targetUsername;
}
// 当前在聊的客服是否在线
if (customer.getOnline_state() == 1) {
return customer.getUsername();
}
}
// 不在线则重新分配
Customer customer = this.customerService.cacheOnlineOne();
if (null == customer) {
return null;
}
while (true) {
customer.setLast_message_user(partyId);
customer.setLast_customer_time(sendTime);
boolean update = customerService.update(customer, true);
if (update) {// 更新成功,退出
break;
} else {// 未成功,说明已下线,重新分配新客服
customer = this.customerService.cacheOnlineOne();
if (null == customer) {
return null;
}
}
}
return customer.getUsername();
}
/**
* 更新未读数
*
* @param partyId
* @param user_customer 更新对象,用户,客服
* @param type read:读write
*/
public void updateUnread(final String partyId, String user_customer, String type) {
MessageUser messageUser = cahce_user.get(partyId);
if (messageUser == null) {
saveCreateByPartyId(partyId);
messageUser = cahce_user.get(partyId);
}
int removeTipNum = 0;
switch (user_customer) {
case "user":
if ("read".equals(type)) {
messageUser.setUser_unreadmsg(0);
} else if ("write".equals(type)) {
messageUser.setUser_unreadmsg(messageUser.getUser_unreadmsg() + 1);
messageUser.setDelete_status(0);
}
break;
case "customer":
if ("read".equals(type)) {
removeTipNum = messageUser.getCustomer_unreadmsg();
messageUser.setCustomer_unreadmsg(0);
} else if ("write".equals(type)) {
messageUser.setCustomer_unreadmsg(messageUser.getCustomer_unreadmsg() + 1);
messageUser.setDelete_status(0);
final String targetUsername = this.userSendTarget(partyId, new Date(),
messageUser.getTarget_username());
if (StringUtils.isNotEmpty(targetUsername)
&& !targetUsername.equals(messageUser.getTarget_username())) {
final Customer customer = customerService.cacheByUsername(targetUsername);
// 客服不存在或者回复内容无效则不回复
if (customer != null && customer.getAuto_answer() != null
&& !StringUtils.isEmptyString(customer.getAuto_answer().trim())) {
// 客服自动回复一条
saveSend(partyId, "text", "receive", customer.getAuto_answer(),
targetUsername + "_SYSTEM");
// Thread t = new Thread(new Runnable() {
// @Override
// public void run() {
// // TODO Auto-generated method stub
// // 异步延迟200毫秒发送
// ThreadUtils.sleep(200);
// // 客服自动回复一条
// saveSend(partyId, "text", "receive", customer.getAuto_answer(),
// targetUsername + "_SYSTEM");
// }
// });
// t.start();
}
}
messageUser.setTarget_username(targetUsername);
if (StringUtils.isNotEmpty(targetUsername)) {// 指定的在线客服存在,则发起通知
Tip tip = new Tip();
tip.setBusiness_id(this.cahce_chat.get(partyId).get(0).getId().toString());
tip.setModel(TipConstants.ONLINECHAT);
tip.setTarget_username(targetUsername);
tipService.saveTip(tip);
}
}
break;
}
updateMessageUser(messageUser);
if (removeTipNum > 0) {
removeTips(messageUser.getPartyId(), removeTipNum);
}
}
/**
* 移除通知
*
* @param partyId
* @param removeTipNum
*/
public void removeTips(String partyId, int removeTipNum) {
List<OnlineChatMessage> list = this.cacheGetList(null, removeTipNum, partyId);
List<String> ids = new ArrayList<String>();
for (OnlineChatMessage m : list) {
ids.add(m.getId().toString());
}
tipService.deleteTip(ids);
}
public void updateMessageUser(MessageUser messageUser) {
this.getHibernateTemplate().merge(messageUser);
cahce_user.put(messageUser.getPartyId(), messageUser);
}
// public MessageUser cacheMessageUser(String partyId) {
// return cahce_user.get(partyId);
// }
public void saveCreateByPartyId(String partyId) {
Party party = partyService.cachePartyBy(partyId, true);
if (party == null) {
throw new BusinessException("无效的UID");
}
MessageUser messageUser = cahce_user.get(party.getId().toString());
if (messageUser == null) {
messageUser = new MessageUser();
messageUser.setPartyId(party.getId().toString());
}
messageUser.setUpdateTime(new Date());
this.getHibernateTemplate().saveOrUpdate(messageUser);
cahce_user.put(party.getId().toString(), messageUser);
}
@Override
public MessageUser saveCreate(String uid, String username) {
Party party = partyService.findPartyByUsercode(uid);
if (party == null) {
party = partyService.findPartyByUsername(uid);
if (party == null) {
throw new BusinessException("用户不存在");
}
}
MessageUser messageUser = cahce_user.get(party.getId().toString());
if (messageUser == null) {
messageUser = new MessageUser();
messageUser.setPartyId(party.getId().toString());
}
messageUser.setUpdateTime(new Date());
messageUser.setDelete_status(0);
messageUser.setTarget_username(username);
this.getHibernateTemplate().saveOrUpdate(messageUser);
cahce_user.put(party.getId().toString(), messageUser);
return messageUser;
}
@Override
public void delete(String partyId) {
MessageUser messageUser = cahce_user.get(partyId);
if (messageUser != null) {
messageUser.setDelete_status(-1);
messageUser.setTarget_username(null);
this.updateMessageUser(messageUser);
}
}
@Override
public int getUnreadMsg(String partyId, String type, String targetUsername) {
int unreadmsg = 0;
if (!StringUtils.isNullOrEmpty(partyId)) {
MessageUser messageUser = cahce_user.get(partyId);
if (messageUser != null) {
switch (type) {
case "user":
unreadmsg = messageUser.getUser_unreadmsg();
break;
case "customer":
unreadmsg = messageUser.getCustomer_unreadmsg();
break;
}
}
} else {
Iterator<Entry<String, MessageUser>> it = cahce_user.entrySet().iterator();
while (it.hasNext()) {
Entry<String, MessageUser> entry = it.next();
if (StringUtils.isEmptyString(targetUsername)
|| !targetUsername.equals(entry.getValue().getTarget_username())) {
continue;
}
switch (type) {
case "user":
unreadmsg += entry.getValue().getUser_unreadmsg();
break;
case "customer":
unreadmsg += entry.getValue().getCustomer_unreadmsg();
break;
}
// unreadmsg = unreadmsg + entry.getValue().getUnreadmsg();
}
}
return unreadmsg;
}
/**
* 设置备注
*
* @param partyId
* @param remarks
*/
public String updateResetRemarks(String partyId, String remarks) throws Exception {
if (StringUtils.isEmptyString(remarks) || StringUtils.isEmptyString(remarks.trim())) {
return null;
}
MessageUser messageUser = this.cacheMessageUser(partyId);
if (messageUser == null) {
throw new BusinessException("用户不存在");
}
messageUser.setRemarks(URLDecoder.decode(remarks, "utf-8"));
this.updateMessageUser(messageUser);
return remarks;
}
/**
* 获取用户信息
*
* @param partyId
* @return
*/
public Map<String, Object> getUserInfo(String partyId) {
Party party = partyService.cachePartyBy(partyId, false);
if (party == null) {
throw new BusinessException("用户不存在");
}
MessageUser messageUser = this.cacheMessageUser(partyId);
Map<String, Object> result = new HashMap<String, Object>();
result.put("partyId", partyId);
result.put("remarks", messageUser.getRemarks());
result.put("username", party.getUsername());
result.put("usercode", party.getUsercode());
result.put("last_login_time", DateUtils.format(party.getLast_loginTime(), DateUtils.DF_yyyyMMddHHmmss));
result.put("create_time", DateUtils.format(party.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss));
result.put("role_name", party.getRolename());
result.put("login_ip", party.getLogin_ip());
// result.put("online", userService.isOnline(partyId));
List<UserRecom> parents = userRecomService.getParents(party.getId());
if (!CollectionUtils.isEmpty(parents) && parents.size() >= 1) {
Party parentParty = partyService.cachePartyBy(parents.get(0).getReco_id(), true);
result.put("recom_parent_name", parentParty == null ? null : parentParty.getUsername());
} else {
result.put("recom_parent_name", null);
}
return result;
}
public void init() {
StringBuffer queryString = new StringBuffer(" FROM MessageUser ");
List<MessageUser> list_user = (List<MessageUser>) this.getHibernateTemplate().find(queryString.toString());
for (int i = 0; i < list_user.size(); i++) {
MessageUser item = list_user.get(i);
if (StringUtils.isEmptyString(item.getPartyId())) {
this.cahce_user.put(item.getIp(), item);
} else {
this.cahce_user.put(item.getPartyId(), item);
}
}
queryString = new StringBuffer(" FROM OnlineChatMessage order by createTime desc ");
List<OnlineChatMessage> list_chat = (List<project.onlinechat.OnlineChatMessage>) this.getHibernateTemplate().find(queryString.toString());
for (int i = 0; i < list_chat.size(); i++) {
OnlineChatMessage item = list_chat.get(i);
List<OnlineChatMessage> list = null;
if (StringUtils.isEmptyString(item.getPartyId())) {
list = cahce_chat.get(item.getIp());
} else {
list = cahce_chat.get(item.getPartyId());
}
if (list == null) {
list = new LinkedList<OnlineChatMessage>();
}
list.add(item);
if (StringUtils.isEmptyString(item.getPartyId())) {
this.cahce_chat.put(item.getIp(), list);
} else {
this.cahce_chat.put(item.getPartyId(), list);
}
// this.cahce_chat.put(item.getPartyId(), list);
}
}
public Map<String, List<OnlineChatMessage>> cacheMessageAll() {
return cahce_chat;
}
public Map<String, MessageUser> cacheMessageUserAll() {
return cahce_user;
}
public MessageUser cacheMessageUser(String key) {
return cahce_user.get(key);
}
public List<OnlineChatMessage> cacheMessage(String key) {
return cahce_chat.get(key);
}
public void putMessage(String key, List<OnlineChatMessage> value) {
cahce_chat.put(key, value);
}
public void putMessageUser(String key, MessageUser value) {
cahce_user.put(key, value);
}
public void updateMessageUserByIp(MessageUser messageUser) {
this.getHibernateTemplate().merge(messageUser);
cahce_user.put(messageUser.getIp(), messageUser);
}
public void deleteByIp(String ip) {
MessageUser messageUser = cahce_user.get(ip);
if (messageUser != null) {
messageUser.setDelete_status(-1);
messageUser.setTarget_username(null);
this.updateMessageUserByIp(messageUser);
}
}
/**
* 未分配到客服的用户,分配客服
*
* @return
*/
public void updateNoAnwserUser(String username) {
List<MessageUser> users = new ArrayList<MessageUser>(this.cacheMessageUserAll().values());
org.apache.commons.collections.CollectionUtils.filter(users, new Predicate() {
@Override
public boolean evaluate(Object arg0) {
// TODO Auto-generated method stub
return ((MessageUser) arg0).getCustomer_unreadmsg() > 0
&& StringUtils.isEmptyString(((MessageUser) arg0).getTarget_username());
}
});
if (CollectionUtils.isEmpty(users)) {
return;
}
for (MessageUser user : users) {
user.setTarget_username(username);
if (StringUtils.isEmptyString(user.getPartyId())) {
this.updateMessageUserByIp(user);
} else {
this.updateMessageUser(user);
}
}
}
public OnlineChatMessage getMessageById(String messageId) {
return this.getHibernateTemplate().get(OnlineChatMessage.class, messageId);
}
public void updateMessageDelete(String messageId, String targetUserName) {
OnlineChatMessage onlineChatMessage = getMessageById(messageId);
if (onlineChatMessage.getDelete_status() == -1) {
throw new BusinessException("该消息已撤回");
}
//游客或者登录用户
String userKey = StringUtils.isEmptyString(onlineChatMessage.getPartyId())?onlineChatMessage.getIp():onlineChatMessage.getPartyId();
MessageUser messageUser = cahce_user.get(userKey);
if (StringUtils.isEmptyString(messageUser.getTarget_username())
|| !targetUserName.equals(messageUser.getTarget_username())) {
throw new BusinessException("并非当前客服接手的用户,无法撤回");
}
if (!"receive".equals(onlineChatMessage.getSend_receive())) {
throw new BusinessException("只能撤回客服发送消息");
}
onlineChatMessage.setDelete_status(-1);
this.getHibernateTemplate().update(onlineChatMessage);
List<OnlineChatMessage> list = cahce_chat.get(userKey);
int indexOf = list.indexOf(onlineChatMessage);
list.remove(indexOf);
list.add(indexOf, onlineChatMessage);
cahce_chat.put(userKey, list);
}
@Override
public Page pagedQuery(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para, String roleName_para, String sellerName_para, String targetUserName_para) {
Map<String, Object> parameters = new HashMap<>();
StringBuffer queryString = new StringBuffer("SELECT * FROM ( ");
queryString.append(" SELECT CASE ");
queryString.append(" WHEN buy.USERCODE IS NULL THEN chat.IP ");
queryString.append(" ELSE buy.USERCODE ");
queryString.append(" END AS USERCODE, buy.EMAIL EMAIL, buy.PHONE PHONE, buy.ROLENAME ROLENAME, s.NAME AS sellerName ");
queryString.append(" , chat.REMARKS, chat.UPDATETIME updateTime, chat.TARGET_USERNAME targetUsername, chat.UUID, chat.IP ");
queryString.append(" FROM T_MESSAGE_USER chat ");
queryString.append(" LEFT JOIN PAT_PARTY sale ON sale.UUID = chat.PARTY_ID ");
queryString.append(" LEFT JOIN PAT_PARTY buy ON buy.UUID = chat.PARTY_ID ");
queryString.append(" LEFT JOIN T_MALL_SELLER s ON s.UUID = sale.UUID ");
queryString.append(" ) T WHERE 1=1 ");
if (!StringUtils.isNullOrEmpty(userCode_para)) {
queryString.append(" AND USERCODE =:usercode ");
parameters.put("usercode", userCode_para);
}
if (!StringUtils.isNullOrEmpty(email_para)) {
queryString.append(" AND EMAIL =:email ");
parameters.put("email", email_para);
}
if (!StringUtils.isNullOrEmpty(phone_para)) {
queryString.append(" AND PHONE =:phone ");
parameters.put("phone", phone_para);
}
if (!StringUtils.isNullOrEmpty(roleName_para)) {
queryString.append(" AND ROLENAME =:rolename ");
parameters.put("rolename", roleName_para);
}
if (!StringUtils.isNullOrEmpty(sellerName_para)) {
queryString.append(" AND SALENAME =:sellername ");
parameters.put("sellername", sellerName_para);
}
if (!StringUtils.isNullOrEmpty(targetUserName_para)) {
queryString.append(" AND targetUsername =:targetUserName_para ");
parameters.put("targetUserName_para", targetUserName_para);
}
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setTipService(TipService tipService) {
this.tipService = tipService;
}
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
this.pagedQueryDao = pagedQueryDao;
}
}

View File

@@ -0,0 +1,588 @@
package project.onlinechat.internal;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.web.Page;
import kernel.web.PagedQueryDao;
import org.apache.commons.collections.Predicate;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.*;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import project.log.MoneyLog;
import project.mall.seller.SellerService;
import project.onlinechat.ChatUser;
import project.onlinechat.OnlineChatUserMessage;
import project.onlinechat.OnlineChatUserMessageService;
import project.party.PartyService;
import project.party.model.Party;
import project.party.recom.UserRecomService;
import project.syspara.SysparaService;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class OnlineChatUserMessageServiceImpl extends HibernateDaoSupport implements OnlineChatUserMessageService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private PagedQueryDao pagedQueryDao;
private UserRecomService userRecomService;
private SellerService sellerService;
private JdbcTemplate jdbcTemplate;
private SysparaService sysparaService;
private PartyService partyService;
private Map<String, ChatUser> cache_chatUser = new ConcurrentHashMap<String, ChatUser>();
private Map<String, List<OnlineChatUserMessage>> cache_messages = new ConcurrentHashMap<String, List<OnlineChatUserMessage>>();
@Override
public List<ChatUser> cacheGetMessageUserPage(int pageNo, int pageSize, String currentUserId,String currentLoginType) {
List<ChatUser> list = new ArrayList<ChatUser>(cache_chatUser.values());
ArrayList<ChatUser> result = new ArrayList<>();
// list.stream().filter(s->!(s.getDelete_status()==-1))
for (ChatUser chatUser : list) {
// 过滤已删除的会话
if (chatUser.getDelete_status() == -1) {
continue;
}
// 过滤不含当前用户的会话id
// if (!chatUser.getChat_id().contains(currentUserId)) {
// continue;
// }
// 商家端过滤掉未通过审核和拉黑的买家
if ("shop".equals(currentLoginType)) {
Party start = partyService.getById(chatUser.getStart_id());
if (Objects.isNull(start) ) {
continue;
}
}
// 商家身份登录 并且跟商家id 相等
if ("shop".equals(currentLoginType) && chatUser.getUser_id().equals(currentUserId)) {
result.add(chatUser);
}else if ("user".equals(currentLoginType) && chatUser.getStart_id().equals(currentUserId)){//用户身份登录 并且跟用户id相等
result.add(chatUser);
}
}
Collections.sort(result);
return result;
}
@Override
public List<OnlineChatUserMessage> cacheGetList(String loginType,String messageId, int pageSize, String... chatIds) {
// 根据参数个数判断是直接传入的chatId还是俩个userId
String chatId = "";
List<OnlineChatUserMessage> cache = null;
// 当传入的是俩个userId 会话id有可能是userId1-userId2 , 也有可能是userId2-userId1
if (chatIds.length > 1) {
chatId = chatIds[0] + "-" + chatIds[1];
cache = cache_messages.get(chatId);
if (cache == null) {
chatId = chatIds[1] + "-" + chatIds[0];
cache = cache_messages.get(chatId);
if (cache == null) {
return new LinkedList<>();
}
}
} else {//当传入的是chatId
chatId = chatIds[0];
cache = cache_messages.get(chatId);
if (cache == null) {
return new LinkedList<>();
}
}
List<OnlineChatUserMessage> result = new ArrayList<>();
result.addAll(cache);
// 过滤只展示通过审核的消息 商家端只展示已通过审核的消息
// if ("shop".equals(loginType)) {
// org.apache.commons.collections.CollectionUtils.filter(result, new Predicate() {
// @Override
// public boolean evaluate(Object arg0) {
// OnlineChatUserMessage msg = (OnlineChatUserMessage) arg0;
// return msg.getAuditStatus() == 1 && msg.getDelete_status()==0;
// }
// });
// }else {
// org.apache.commons.collections.CollectionUtils.filter(result, new Predicate() {
// @Override
// public boolean evaluate(Object arg0) {
// OnlineChatUserMessage msg = (OnlineChatUserMessage) arg0;
// return msg.getDelete_status()==0;
// }
// });
// }
int start = cacheIndex(messageId, result);
// start = start == 0 ? start : start + 1;// 空消息则表示首页,消息索引的后一条为起始
int end = start + pageSize;
if (start >= result.size()) {// 起始数据大于总量,返回空
return new LinkedList<OnlineChatUserMessage>();
}
if (cache.size() <= end)
end = result.size();
List<OnlineChatUserMessage> list = result.subList(start, end>=result.size()?result.size():end);
return list;
}
@Override
public OnlineChatUserMessage saveSend(String startId, String sellerId, String type, String sendType, String content ,int messageDeleteType,String loginType) {
// 会话关系在这里根据登录类型确定为第一个id为用户id或者游客ip 后一个id必须为商家id
OnlineChatUserMessage onlineChatUserMessage = new OnlineChatUserMessage();
Party sender = partyService.getById(startId);
if (Objects.isNull(sender)) {
throw new BusinessException("请重新登录");
}
String chatId = startId + "-" + sellerId;
onlineChatUserMessage.setChatId(chatId);
if ("user".equals(loginType) && "send".equals(sendType)) {//用户端登录并且是发送类型的才是买家消息发送
onlineChatUserMessage.setSendId(startId);
onlineChatUserMessage.setAuditStatus(sender.getChatAudit());
onlineChatUserMessage.setSendType(1);//标记用户发送消息类型为1
}else {
onlineChatUserMessage.setSendId(sellerId);
onlineChatUserMessage.setAuditStatus(1);
onlineChatUserMessage.setSendType(0);//标记商家用户消息类型为0
}
onlineChatUserMessage.setContentType(type);
onlineChatUserMessage.setContent(content);
onlineChatUserMessage.setCreateTime(new Date());
onlineChatUserMessage.setDelete_status(messageDeleteType);
this.getHibernateTemplate().save(onlineChatUserMessage);
List<OnlineChatUserMessage> list = cache_messages.get(chatId);
if (list == null) {
list = new LinkedList<OnlineChatUserMessage>();
}
list.add(onlineChatUserMessage);
Collections.sort(list);
Collections.reverse(list);// 添加完后,时间倒叙排序加回
this.cache_messages.put(chatId, list);
if (!cache_chatUser.containsKey(chatId)) {// 不存在该会话则新建该会话
ChatUser chatUser = cache_chatUser.get(chatId);
if (chatUser == null) {
chatUser = new ChatUser();
chatUser.setChat_id(chatId);
chatUser.setStart_id(startId);
chatUser.setUser_id(sellerId);
}
// 会话创建的时候才给更新时间
chatUser.setUpdateTime(new Date());
chatUser.setDelete_status(0);
this.getHibernateTemplate().saveOrUpdate(chatUser);
cache_chatUser.put(chatId, chatUser);
}
ChatUser currentChatUser = cache_chatUser.get(chatId);
if ("send".equals(sendType) && messageDeleteType==0) {//买家是消息发送者
if (onlineChatUserMessage.getAuditStatus()==1) {
currentChatUser.setUser_unread(currentChatUser.getUser_unread() + 1);
}
if (onlineChatUserMessage.getAuditStatus()==0) {
currentChatUser.setUnAuditUnread(currentChatUser.getUnAuditUnread()+1);
}
}else if(messageDeleteType==0 && "receive".equals(sendType)){//买家是消息发送者
currentChatUser.setStart_unread(currentChatUser.getStart_unread() + 1);
}
currentChatUser.setDelete_status(0);
// 2023-06-15 新增需求 发送消息更新会话关系表的会话更新时间
currentChatUser.setUpdateTime(new Date());
updateChatUserByChatId(currentChatUser);
return onlineChatUserMessage;
}
@Override
public int getUnreadMsg(String currentUserId, String loginType) {
int unreadmsg = 0;
Iterator<Map.Entry<String, ChatUser>> it = cache_chatUser.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, ChatUser> entry = it.next();
ChatUser chatUser = entry.getValue();
if ("shop".equals(loginType)) {//当前用户以商家身份登录时当前用户id为User_id
if (chatUser.getUser_id().contains(currentUserId)) {//会话中包含当前用户
unreadmsg += chatUser.getUser_unread();
}
}else if ("user".equals(loginType)){
if (chatUser.getStart_id().contains(currentUserId)) {
unreadmsg += chatUser.getStart_unread();
}
}
}
return unreadmsg;
}
@Override
public long getTotalCountMsg(String loginPartyId) {
// Criteria criteria = this.getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(ChatUser.class);
// ProjectionList projectionList = Projections.projectionList()
// .add(Projections.sum("user_unread"))
// .add(Projections.sum("unAuditUnread"));
// criteria.setProjection(projectionList);
// Object[] results = (Object[]) criteria.uniqueResult();
// Long totalUnreadCount = (Long) results[0] + (Long) results[1];
// 2023-01-04 需求修改为只查询未审核状态会员发送的消息 2023-09-08 修改为只查询代理下的用户
String hql = "SELECT SUM(u.unAuditUnread) FROM ChatUser u ";
List children = this.userRecomService.findChildren(loginPartyId);
if (children != null && !children.isEmpty()) {
hql += " WHERE u.start_id IN (:userIds)";
}
Query query = this.getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hql);
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
if (children.size() == 0) {
return 0L;
}
if (children != null && !children.isEmpty()) {
query.setParameterList("userIds", children);
}
}
Long totalUnreadCount = (Long) query.uniqueResult();
return totalUnreadCount != null ? totalUnreadCount : 0L;
}
@Override
public Map<String, Object> getBuyUnreadCount(String loginPartyId) {
//查询虚拟用户与登录的代理下的商家的未读总数
Map<String, Object> countResult = new HashMap<>();
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
Map<String, Object> parameters = new HashMap<>();
List children = this.userRecomService.findChildren(loginPartyId);
if (children.size() == 0) {
countResult.put("count", new Integer(0));
return countResult;
}
log.info("---> OnlineChatUserMessageServiceImpl getBuyUnreadCount 当前用户:{} 有下级用户数量为:{} 个", loginPartyId, children.size());
String sql = "SELECT IFNULL(SUM(START_UNREAD),0) FROM T_CHAT_USER chat, PAT_PARTY p WHERE chat.START_ID=p.UUID AND p.ROLENAME='GUEST' AND chat.USER_ID IN (?0)";
log.info("---> OnlineChatUserMessageServiceImpl getBuyUnreadCount sql:{}, children:{}", sql, children);
NativeQuery<Object[]> nativeQuery = this.getHibernateTemplate().getSessionFactory().getCurrentSession().createNativeQuery(sql);
nativeQuery = this.getHibernateTemplate().getSessionFactory().getCurrentSession().createNativeQuery(sql);
nativeQuery.setParameter(0, children);
countResult.put("count", nativeQuery.getSingleResult());
return countResult;
}
StringBuffer sql = new StringBuffer(" SELECT IFNULL(SUM(START_UNREAD),0) FROM T_CHAT_USER chat,PAT_PARTY p WHERE chat.START_ID=p.UUID AND p.ROLENAME='GUEST' ");
log.info("---> OnlineChatUserMessageServiceImpl getBuyUnreadCount sql:{}", sql);
NativeQuery<Object[]> nativeQuery = this.getHibernateTemplate().getSessionFactory().getCurrentSession()
.createNativeQuery(sql.toString());
Object result = nativeQuery.getSingleResult();
countResult.put("count", result);
return countResult;
}
// 调用消息记录接口时候,更新未读数
@Override
public void updateUnread(String currentUserPartyId, String chatId) {
ChatUser chatUser = cache_chatUser.get(chatId);
if (chatUser == null) {
saveCreate(chatId);
chatUser = cache_chatUser.get(chatId);
}//更新当前用户未读数字
if (chatUser.getStart_id().equals(currentUserPartyId)) {
chatUser.setStart_unread(0);
}
if (chatUser.getUser_id().equals(currentUserPartyId)){
chatUser.setUser_unread(0);
}
updateChatUserByChatId(chatUser);
}
/**
* 获取消息的索引
*/
private int cacheIndex(String messageId, List<OnlineChatUserMessage> list) {
if (StringUtils.isEmptyString(messageId))
return 0;
int index = -1;
for (int i = 0; i < list.size(); i++) {
OnlineChatUserMessage message = list.get(i);
if (messageId.equals(message.getId().toString())) {
index = i;
}
}
if (index == -1) {
throw new BusinessException("参数异常,消息获取失败");
}
return index + 1;
}
public ChatUser cacheChatUser(String key) {
return cache_chatUser.get(key);
}
public ChatUser findChatUserById(String id) {
return getHibernateTemplate().get(ChatUser.class, id);
}
@Override
public ChatUser saveCreate(String chatId) {
ChatUser chatUser = cache_chatUser.get(chatId);
if (chatUser == null) {
chatUser = new ChatUser();
chatUser.setChat_id(chatId);
String[] split = chatId.split("-");
chatUser.setStart_id(split[0]);
chatUser.setUser_id(split[1]);
}
chatUser.setUpdateTime(new Date());
chatUser.setDelete_status(0);
this.getHibernateTemplate().saveOrUpdate(chatUser);
// 入库的时候就需要更新缓存
cache_chatUser.put(chatId, chatUser);
return chatUser;
}
@Override
public Page pagedQuery(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para, String roleName_para,
String sellerName_para,String loginPartyId, String sellerCode, String sellerRoleName) {
Map<String, Object> parameters = new HashMap<>();
StringBuffer queryString = new StringBuffer(
"SELECT buy.USERCODE AS USERCODE, buy.EMAIL, buy.PHONE, buy.ROLENAME, sale.USERCODE AS SALECODE ");
queryString.append(" , s.NAME, sale.REMARKS remarks, sale.UUID partyId, chat.UPDATETIME, chat.CHAT_ID, chat.START_UNREAD AS UNREAD,chat.UUID id ");
queryString.append(" , sale.ROLENAME sellerRoleName, sale.USERCODE sellerCode ");
queryString.append(" FROM T_CHAT_USER chat ");
queryString.append(" INNER JOIN PAT_PARTY buy ON buy.UUID = chat.START_ID AND buy.ROLENAME='GUEST' ");
queryString.append(" LEFT JOIN PAT_PARTY sale ON sale.UUID = chat.USER_ID AND sale.ROLE_TYPE = '1' ");
queryString.append(" LEFT JOIN T_MALL_SELLER s ON s.UUID = sale.UUID ");
queryString.append(" WHERE 1 = 1 ");
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
List children = this.userRecomService.findChildren(loginPartyId);
if (children.size() == 0) {
return new Page();
}
queryString.append(" and sale.UUID in (:children) ");
parameters.put("children", children);
}
if (!StringUtils.isNullOrEmpty(userCode_para)) {
queryString.append(" AND buy.USERCODE =:usercode ");
parameters.put("usercode", userCode_para);
}
if (!StringUtils.isNullOrEmpty(email_para)) {
queryString.append(" AND buy.EMAIL =:email ");
parameters.put("email", email_para);
}
if (!StringUtils.isNullOrEmpty(phone_para)) {
queryString.append(" AND buy.PHONE =:phone ");
parameters.put("phone", phone_para);
}
if (!StringUtils.isNullOrEmpty(roleName_para)) {
queryString.append(" AND buy.ROLENAME =:rolename ");
parameters.put("rolename", roleName_para);
}
if (!StringUtils.isNullOrEmpty(sellerName_para)) {
queryString.append(" AND s.NAME =:sellername ");
parameters.put("sellername", sellerName_para);
}
if (!StringUtils.isNullOrEmpty(sellerCode)) {
queryString.append(" AND sale.USERCODE =:sellerCode ");
parameters.put("sellerCode", sellerCode);
}
if (!StringUtils.isNullOrEmpty(sellerRoleName)) {
queryString.append(" AND sale.ROLENAME =:sellerRoleName ");
parameters.put("sellerRoleName", sellerRoleName);
}
queryString.append(" ORDER BY chat.UPDATETIME desc ");
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
@Override
public Page pagedQueryAudit(int pageNo, int pageSize, String userCode_para, String email_para, String phone_para,String chatAudit_para,String loginPartyId) {
Map<String, Object> parameters = new HashMap<>();
StringBuffer queryString = new StringBuffer(
" SELECT sender.UUID,sender.USERCODE,sender.EMAIL,sender.PHONE,sender.ROLENAME,msg.CONTENT,msg.CREATE_TIME,sender.CHAT_AUDIT, "+
" seller.NAME AS sellerName, sellerP.USERCODE AS sellerCode "+
" FROM T_ONLINECHAT_USERMESSAGE msg "+
" LEFT JOIN PAT_PARTY sender ON sender.UUID = msg.SEND_ID "+
" LEFT JOIN T_CHAT_USER user ON user.CHAT_ID = msg.CHAT_ID "+
" LEFT JOIN T_MALL_SELLER seller ON user.USER_ID = seller.UUID "+
" LEFT JOIN PAT_PARTY sellerP ON sellerP.UUID = seller.UUID "+
" WHERE SEND_TYPE = 1 AND sender.ROLENAME ='MEMBER' ");
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
List children = this.userRecomService.findChildren(loginPartyId);
if (children.size() == 0) {
return new Page();
}
queryString.append(" AND user.START_ID in (:children) ");
parameters.put("children", children);
}
if (!StringUtils.isNullOrEmpty(userCode_para)) {
queryString.append(" AND sender.USERCODE =:usercode ");
parameters.put("usercode", userCode_para);
}
if (!StringUtils.isNullOrEmpty(email_para)) {
queryString.append(" AND sender.EMAIL =:email ");
parameters.put("email", email_para);
}
if (!StringUtils.isNullOrEmpty(phone_para)) {
queryString.append(" AND sender.PHONE =:phone ");
parameters.put("phone", phone_para);
}
if (!StringUtils.isNullOrEmpty(chatAudit_para)) {
queryString.append(" AND sender.CHAT_AUDIT =:chatAudit ");
parameters.put("chatAudit", chatAudit_para);
}
queryString.append(" ORDER BY msg.CREATE_TIME desc ");
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
public void updateChatUserByChatId(ChatUser chatUser) {
this.getHibernateTemplate().saveOrUpdate(chatUser);
// this.getHibernateTemplate().flush();
cache_chatUser.put(chatUser.getChat_id(), chatUser);
}
public void init() {
StringBuffer queryString = new StringBuffer(" FROM ChatUser ");
List<ChatUser> list_user = (List<ChatUser>) this.getHibernateTemplate().find(queryString.toString());
for (int i = 0; i < list_user.size(); i++) {
ChatUser item = list_user.get(i);
cache_chatUser.put(item.getChat_id(), item);
}
queryString = new StringBuffer(" FROM OnlineChatUserMessage order by createTime desc ");
List<OnlineChatUserMessage> list_chat = (List<OnlineChatUserMessage>) this.getHibernateTemplate().find(queryString.toString());
for (int i = 0; i < list_chat.size(); i++) {
OnlineChatUserMessage item = list_chat.get(i);
List<OnlineChatUserMessage> list = null;
list = cache_messages.get(item.getChatId());
if (list == null) {
list = new LinkedList<>();
}
list.add(item);
this.cache_messages.put(item.getChatId(), list);
}
}
public OnlineChatUserMessage getLastImMessage(String senderId, String receiverId, boolean includeImg, Long optionLimitTime) {
if (StringUtils.isNullOrEmpty(senderId) || StringUtils.isNullOrEmpty(receiverId)) {
throw new RuntimeException("缺少必须参数");
}
DetachedCriteria query = DetachedCriteria.forClass(OnlineChatUserMessage.class);
query.add(Property.forName("chatId").eq(senderId + "-" + receiverId));
if (optionLimitTime != null && optionLimitTime > 0) {
Date limitSendTime = new Date(optionLimitTime);
query.add(Property.forName("createTime").ge(limitSendTime));
}
if (!includeImg) {
query.add(Property.forName("contentType").eq("text"));
}
query.addOrder(Order.desc("createTime"));
List<OnlineChatUserMessage> list = (List<OnlineChatUserMessage>) getHibernateTemplate().findByCriteria(query,0,1);
if (list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
@Override
public boolean checkChat(String currentUserPartyId, String sellerId) {
return this.cache_chatUser.containsKey(currentUserPartyId+"-"+sellerId) || this.cache_chatUser.containsKey(sellerId+"-"+currentUserPartyId);
}
@Override
public void updateAutoClearChatHistory() {
String mallChatHistoryDeleteDays = this.sysparaService.find("mall_chat_history_delete").getValue();
if (Objects.isNull(mallChatHistoryDeleteDays)) {
logger.error("mall_chat_history_delete参数未配置");
return;
}
String needToClearTime = DateUtils.toString(DateUtils.addDate(new Date(), -Integer.valueOf(mallChatHistoryDeleteDays)));
jdbcTemplate.execute("DELETE FROM T_ONLINECHAT_MESSAGE WHERE CREATE_TIME<'" + needToClearTime + "'");
jdbcTemplate.execute("DELETE FROM T_ONLINECHAT_USERMESSAGE WHERE CREATE_TIME<'" + needToClearTime + "'");
}
@Override
public void addWhite(String partyId) {
Set<String> chatIds = cache_chatUser.keySet();
for (String chatId : chatIds) {
if (chatId.startsWith(partyId)) {
// 将这个未审核的未读数字加到已审核未读数上
ChatUser chatUser = cache_chatUser.get(chatId);
int unAuditUnread = chatUser.getUnAuditUnread();
int user_unread = chatUser.getUser_unread();
chatUser.setUser_unread(user_unread+unAuditUnread);
chatUser.setUnAuditUnread(0);
this.updateChatUserByChatId(chatUser);
cache_chatUser.put(chatId,chatUser);
// 将这个已通过审核的聊天消息由未审核状态变成已审核状态
List<OnlineChatUserMessage> onlineChatUserMessages = cache_messages.get(chatId);
for (OnlineChatUserMessage onlineChatUserMessage : onlineChatUserMessages) {
if (onlineChatUserMessage.getAuditStatus()==0) {
onlineChatUserMessage.setAuditStatus(1);
this.getHibernateTemplate().saveOrUpdate(onlineChatUserMessage);
}
}
cache_messages.put(chatId,onlineChatUserMessages);
}
}
}
@Override
public void addBlack(String partyId) {
Set<String> chatIds = cache_chatUser.keySet();
for (String chatId : chatIds) {
if (chatId.startsWith(partyId)) {
// 将这个已拉黑用户的未审核的消息未读数字设置成0
ChatUser chatUser = cache_chatUser.get(chatId);
chatUser.setUnAuditUnread(0);
chatUser.setUser_unread(0);
this.updateChatUserByChatId(chatUser);
cache_chatUser.put(chatId,chatUser);
// 将这个已拉黑的用户的未审核的聊天消息由未审核状态变成了拉黑状态
List<OnlineChatUserMessage> onlineChatUserMessages = cache_messages.get(chatId);
for (OnlineChatUserMessage onlineChatUserMessage : onlineChatUserMessages) {
if (onlineChatUserMessage.getAuditStatus()==0) {
onlineChatUserMessage.setAuditStatus(-1);
this.getHibernateTemplate().saveOrUpdate(onlineChatUserMessage);
}
}
cache_messages.put(chatId,onlineChatUserMessages);
}
}
}
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
this.pagedQueryDao = pagedQueryDao;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
}

View File

@@ -0,0 +1,208 @@
package project.onlinechat.internal;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import kernel.exception.BusinessException;
import kernel.util.StringUtils;
import project.onlinechat.MessageUser;
import project.onlinechat.OnlineChatMessage;
import project.onlinechat.OnlineChatMessageService;
import project.onlinechat.OnlineChatVisitorMessageService;
import project.tip.TipConstants;
import project.tip.TipService;
import project.tip.model.Tip;
import systemuser.CustomerService;
import systemuser.model.Customer;
public class OnlineChatVisitorMessageServiceImpl extends HibernateDaoSupport
implements OnlineChatVisitorMessageService {
private OnlineChatMessageService onlineChatMessageService;
private TipService tipService;
private CustomerService customerService;
@Override
public OnlineChatMessage saveSend(String ip, String type, String send_receive, String content, String username) {
OnlineChatMessage onlineChatMessage = new OnlineChatMessage();
// onlineChatMessage.setPartyId(ip);
onlineChatMessage.setType(type);
onlineChatMessage.setSend_receive(send_receive);
onlineChatMessage.setContent(content);
onlineChatMessage.setCreateTime(new Date());
onlineChatMessage.setUsername(username);
onlineChatMessage.setIp(ip);
this.getHibernateTemplate().save(onlineChatMessage);
List<OnlineChatMessage> list = onlineChatMessageService.cacheMessage(ip);
if (list == null) {
list = new LinkedList<OnlineChatMessage>();
}
list.add(onlineChatMessage);
Collections.sort(list);
Collections.reverse(list);// 添加完后,时间倒叙排序加回
onlineChatMessageService.putMessage(ip, list);
if (onlineChatMessageService.cacheMessageUser(ip) == null) {// 不存在则添加用户
saveCreate(ip,username);
}
switch (send_receive) {
case "receive":// 客服发送
updateUnread(ip, "user", "write");
break;
case "send":// 用户发送
updateUnread(ip, "customer", "write");
// tipService.saveTip(onlineChatMessage.getId().toString(), TipConstants.ONLINECHAT);
break;
}
return onlineChatMessage;
}
/**
* 更新未读数
*
* @param ip
* @param user_customer 更新对象,用户,客服
* @param type read:读write
*/
public void updateUnread(final String ip, String user_customer, String type) {
MessageUser messageUser = onlineChatMessageService.cacheMessageUser(ip);
if (messageUser == null) {
saveCreate(ip,null);
messageUser = onlineChatMessageService.cacheMessageUser(ip);
}
int removeTipNum = 0;
switch (user_customer) {
case "user":
if ("read".equals(type)) {
messageUser.setUser_unreadmsg(0);
} else if ("write".equals(type)) {
messageUser.setUser_unreadmsg(messageUser.getUser_unreadmsg() + 1);
messageUser.setDelete_status(0);
}
break;
case "customer":
if ("read".equals(type)) {
removeTipNum = messageUser.getCustomer_unreadmsg();
messageUser.setCustomer_unreadmsg(0);
} else if ("write".equals(type)) {
messageUser.setCustomer_unreadmsg(messageUser.getCustomer_unreadmsg() + 1);
messageUser.setDelete_status(0);
final String targetUsername = onlineChatMessageService.userSendTarget(ip, new Date(), messageUser.getTarget_username());
if (StringUtils.isNotEmpty(targetUsername)
&& !targetUsername.equals(messageUser.getTarget_username())) {
final Customer customer = customerService.cacheByUsername(targetUsername);
// 客服不存在或者回复内容无效则不回复
if (customer != null && customer.getAuto_answer() != null
&& !StringUtils.isEmptyString(customer.getAuto_answer().trim())) {
// 客服自动回复一条
saveSend(ip, "text", "receive", customer.getAuto_answer(), targetUsername + "_SYSTEM");
// Thread t = new Thread(new Runnable() {
// @Override
// public void run() {
// // TODO Auto-generated method stub
// // 异步延迟200毫秒发送
// ThreadUtils.sleep(200);
// saveSend(ip, "text", "receive", customer.getAuto_answer(), targetUsername + "_SYSTEM");// 客服自动回复一条
// }
// });
// t.start();
}
}
messageUser.setTarget_username(targetUsername);
if (StringUtils.isNotEmpty(targetUsername)) {// 指定的在线客服存在,则发起通知
Tip tip = new Tip();
tip.setBusiness_id(onlineChatMessageService.cacheMessage(ip).get(0).getId().toString());
tip.setModel(TipConstants.ONLINECHAT);
tip.setTarget_username(targetUsername);
tipService.saveTip(tip);
}
}
break;
}
onlineChatMessageService.updateMessageUserByIp(messageUser);
if (removeTipNum > 0)
onlineChatMessageService.removeTips(messageUser.getIp(), removeTipNum);
}
@Override
public MessageUser saveCreate(String ip,String username) {
MessageUser messageUser = onlineChatMessageService.cacheMessageUser(ip);
if (messageUser == null) {
messageUser = new MessageUser();
messageUser.setIp(ip);
}
messageUser.setUpdateTime(new Date());
messageUser.setDelete_status(0);
messageUser.setTarget_username(username);
this.getHibernateTemplate().saveOrUpdate(messageUser);
onlineChatMessageService.putMessageUser(ip, messageUser);
return messageUser;
}
/**
* 设置备注
*
* @param ip
* @param remarks
*/
public String updateResetRemarks(String ip, String remarks) throws Exception {
if (StringUtils.isEmptyString(remarks) || StringUtils.isEmptyString(remarks.trim())) {
return null;
}
MessageUser messageUser = onlineChatMessageService.cacheMessageUser(ip);
if (messageUser == null) {
throw new BusinessException("用户不存在");
}
messageUser.setRemarks(URLDecoder.decode(remarks, "utf-8"));
onlineChatMessageService.updateMessageUserByIp(messageUser);
return remarks;
}
/**
* 获取用户信息
*
* @param ip
* @return
*/
public Map<String, Object> getUserInfo(String ip) {
MessageUser messageUser = this.onlineChatMessageService.cacheMessageUser(ip);
Map<String, Object> result = new HashMap<String, Object>();
result.put("partyId", ip);
result.put("remarks", messageUser.getRemarks());
// result.put("username", party.getUsername());
// result.put("usercode", party.getUsercode());
// result.put("last_login_time", DateUtils.format(party.getLast_loginTime(),DateUtils.DF_yyyyMMddHHmmss));
// result.put("create_time", DateUtils.format(party.getCreateTime(),DateUtils.DF_yyyyMMddHHmmss));
// result.put("role_name", party.getRolename());
// result.put("login_ip", party.getLogin_ip());
// List<UserRecom> parents = userRecomService.getParents(party.getId());
// if(!CollectionUtils.isEmpty(parents)&&parents.size()>=2) {
// Party parentParty = partyService.cachePartyBy(parents.get(1).getPartyId(), true);
// result.put("recom_parent_name", parentParty==null?null:parentParty.getUsername());
// }else {
// result.put("recom_parent_name", null);
// }
return result;
}
public void setOnlineChatMessageService(OnlineChatMessageService onlineChatMessageService) {
this.onlineChatMessageService = onlineChatMessageService;
}
public void setTipService(TipService tipService) {
this.tipService = tipService;
}
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
}

View File

@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.onlinechat.ChatUser" table="T_CHAT_USER">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="chat_id" type="java.lang.String">
<column name="CHAT_ID" />
</property>
<property name="start_id" type="java.lang.String">
<column name="START_ID" />
</property>
<property name="user_id" type="java.lang.String">
<column name="USER_ID" />
</property>
<property name="start_unread" type="int">
<column name="START_UNREAD" />
</property>
<property name="user_unread" type="int">
<column name="USER_UNREAD" />
</property>
<property name="unAuditUnread" type="int">
<column name="UN_AUDIT_UNREAD" />
</property>
<property name="updateTime" type="timestamp">
<column name="UPDATETIME" />
</property>
<property name="delete_status" type="int">
<column name="DELETE_STATUS" />
</property>
<property name="remarks" type="java.lang.String">
<column name="REMARKS" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.onlinechat.MessageUser" table="T_MESSAGE_USER">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="partyId" type="java.lang.String">
<column name="PARTY_ID" />
</property>
<!-- <property name="unreadmsg" type="int">
<column name="UNREAD_MSG" />
</property> -->
<property name="user_unreadmsg" type="int">
<column name="USER_UNREADMSG" />
</property>
<property name="customer_unreadmsg" type="int">
<column name="CUSTOMER_UNREADMSG" />
</property>
<property name="updateTime" type="timestamp">
<column name="UPDATETIME" />
</property>
<property name="delete_status" type="int">
<column name="DELETE_STATUS" />
</property>
<property name="remarks" type="java.lang.String">
<column name="REMARKS" />
</property>
<property name="ip" type="java.lang.String">
<column name="IP" />
</property>
<property name="target_username" type="java.lang.String">
<column name="TARGET_USERNAME" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.onlinechat.OnlineChatMessage" table="T_ONLINECHAT_MESSAGE">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="partyId" type="java.lang.String">
<column name="PARTY_ID" />
</property>
<property name="send_receive" type="java.lang.String">
<column name="SEND_RECEIVE" />
</property>
<property name="type" type="java.lang.String">
<column name="CONTENT_TYPE" />
</property>
<property name="content" type="java.lang.String">
<column name="CONTENT" />
</property>
<property name="createTime" type="timestamp">
<column name="CREATE_TIME" />
</property>
<property name="username" type="java.lang.String">
<column name="USERNAME" />
</property>
<property name="ip" type="java.lang.String">
<column name="IP" />
</property>
<property name="delete_status" type="int">
<column name="DELETE_STATUS" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.onlinechat.OnlineChatUserMessage" table="T_ONLINECHAT_USERMESSAGE">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="chatId" type="java.lang.String">
<column name="CHAT_ID" />
</property>
<property name="sendId" type="java.lang.String">
<column name="SEND_ID" />
</property>
<property name="sendType" type="int">
<column name="SEND_TYPE" />
</property>
<property name="contentType" type="java.lang.String">
<column name="CONTENT_TYPE" />
</property>
<property name="content" type="java.lang.String">
<column name="CONTENT" />
</property>
<property name="createTime" type="timestamp">
<column name="CREATE_TIME" />
</property>
<property name="delete_status" type="int">
<column name="DELETE_STATUS" />
</property>
<property name="auditStatus" type="int">
<column name="AUDIT_STATUS" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,529 @@
package project.web.admin;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.JsonUtils;
import kernel.util.StringUtils;
import kernel.web.PageActionSupport;
import kernel.web.ResultObject;
import project.onlinechat.MessageUser;
import project.onlinechat.OnlineChatMessage;
import project.onlinechat.OnlineChatMessageService;
import project.onlinechat.OnlineChatVisitorMessageService;
import project.party.PartyService;
import project.party.model.Party;
import project.redis.RedisHandler;
import project.user.UserRedisKeys;
import project.user.token.Token;
import project.user.token.TokenService;
import systemuser.CustomerService;
import systemuser.model.Customer;
@RestController
public class NewAdminOnlineChatController extends PageActionSupport {
private Logger logger = LogManager.getLogger(NewAdminOnlineChatController.class);
@Autowired
OnlineChatMessageService onlineChatMessageService;
@Autowired
OnlineChatVisitorMessageService onlineChatVisitorMessageService;
@Autowired
PartyService partyService;
@Autowired
CustomerService customerService;
@Autowired
TokenService tokenService;
@Autowired
RedisHandler redisHandler;
private final String action = "public/newAdminOnlineChatAction!";
/**
* 在线聊天-人员列表
*/
@RequestMapping(value = action + "userlist.action", produces="text/html;charset=UTF-8")
public String userlist(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
int pageno = 1;
if (null != request.getParameter("page_no")) {
pageno = Integer.valueOf(request.getParameter("page_no"));
}
String token = request.getParameter("token");
int pageSize = 50;
List<MessageUser> list = onlineChatMessageService
.cacheGetMessageUserPage(pageno, pageSize, this.tokenService.cacheGet(token));
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", list.get(i).getId());
Party party = null;
party=this.partyService.cachePartyBy(list.get(i).getPartyId(), true);
if (party != null) {
map.put("username", party.getUsername());
map.put("uid", party.getUsercode());
map.put("partyid", party.getId().toString());
// 2023-04-24 需求修改,增加离开状态,用户状态为 在线1 离开2 离线3 超过10分钟算状态2 离开
ConcurrentHashMap statusParams = (ConcurrentHashMap) redisHandler
.get(UserRedisKeys.ONLINE_USER_STATUS_PARTYID + party.getId().toString());
if (Objects.nonNull(statusParams) &&
DateUtils.calcTimeBetween("s", (Date)statusParams.get("operateTime"), new Date())>300) {
// 这里一旦不发送心跳以后操作时间超过10分钟操作时间没有更新算离线手动退出登录也算离线
statusParams.put("status",3);
redisHandler.setSync(UserRedisKeys.ONLINE_USER_STATUS_PARTYID + party.getId().toString(),statusParams);
}
int status = Optional.ofNullable(statusParams).map(s->(int)s.get("status")).orElse(3);
map.put("online",status);
} else {
map.put("username", list.get(i).getIp());
map.put("partyid", list.get(i).getIp());
}
map.put("remarks", list.get(i).getRemarks());
map.put("unreadmsg", list.get(i).getCustomer_unreadmsg());
List<OnlineChatMessage> chats = onlineChatMessageService.cacheGetList(null, 1,
StringUtils.isNullOrEmpty(list.get(i).getPartyId()) ? list.get(i).getIp() : list.get(i).getPartyId());
String content = "";
Date chatDate = null;
if (chats.size() > 0) {
chatDate = chats.get(0).getCreateTime();
if ("img".equals(chats.get(0).getType())) {
content = "[picture]";
} else {
content = chats.get(0).getContent();
}
}
map.put("content", content);
map.put("updatetime",
DateUtils.format(chatDate != null ? chatDate : list.get(i).getUpdateTime(), "MM-dd HH:mm"));
map.put("order_updatetime", chatDate != null&&chatDate.after(list.get(i).getUpdateTime()) ? chatDate : list.get(i).getUpdateTime());// 用作排序
data.add(map);
}
Collections.sort(data, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> paramT1, Map<String, Object> paramT2) {
Date date1 = (Date) paramT1.get("order_updatetime");
Date date2 = (Date) paramT2.get("order_updatetime");
return -date1.compareTo(date2);
}
});
int start = 0;
int end = start + pageSize;
if (data.size() <= end) {
end = data.size();
}
List<Map<String, Object>> resultData = new ArrayList<Map<String, Object>>();
resultData.addAll(data);
List<Map<String, Object>> subList = resultData.subList(start, end);
resultObject.setData(subList);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("系统聊天获取聊天用户列表报错msg:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 聊天记录列表
*/
@RequestMapping(value = action + "list.action", produces="text/html;charset=UTF-8")
public String list(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String message_id = request.getParameter("message_id");
String partyid = request.getParameter("partyid");
List<OnlineChatMessage> list = onlineChatMessageService.cacheGetList(message_id, 30, partyid);
// 首页的时候才更新未读数
if (StringUtils.isNullOrEmpty(message_id) && !StringUtils.isNullOrEmpty(partyid)) {
MessageUser cacheMessageUser = onlineChatMessageService.cacheMessageUser(partyid);
// ip表示游客
if (partyid.indexOf(".") != -1 || partyid.indexOf(":") != -1) {
if (cacheMessageUser != null && cacheMessageUser.getCustomer_unreadmsg() > 0) {
onlineChatVisitorMessageService.updateUnread(partyid, "customer", "read");
}
} else {
if (cacheMessageUser != null && cacheMessageUser.getCustomer_unreadmsg() > 0) {
onlineChatMessageService.updateUnread(partyid, "customer", "read");
}
}
}
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
int status=1;
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", list.get(i).getId().toString());
map.put("send_receive", list.get(i).getSend_receive());
String type = list.get(i).getType();
map.put("type", type);
String content = list.get(i).getContent();
// if ("img".equals(type)) {
// content = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + content;
// }
map.put("content", content);
map.put("createtime", DateUtils.format(list.get(i).getCreateTime(), "MM-dd HH:mm"));
map.put("delete_status", list.get(i).getDelete_status());
// 聊天记录增加在线状态记录显示
if ("send".equals(list.get(i).getSend_receive())&&(!StringUtils.isNullOrEmpty(partyid)) && (!(partyid.contains(".") || partyid.contains(":")))) {
ConcurrentHashMap statusParams = (ConcurrentHashMap) redisHandler.get(UserRedisKeys.ONLINE_USER_STATUS_PARTYID + partyid);
if (Objects.nonNull(statusParams) &&
DateUtils.calcTimeBetween("s", (Date)statusParams.get("operateTime"), new Date())>300) {
statusParams.put("status",3);
redisHandler.setSync(UserRedisKeys.ONLINE_USER_STATUS_PARTYID + partyid,statusParams);
}
status = Optional.ofNullable(statusParams).map(s->(int)s.get("status")).orElse(3);
map.put("online",status);
}
data.add(map);
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 发送消息
*
*/
@RequestMapping(value = action + "send.action", produces="text/html;charset=UTF-8")
public String send(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
String token = request.getParameter("token");
if (StringUtils.isNullOrEmpty(token)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return JsonUtils.getJsonString(resultObject);
}
String partyId = tokenService.cacheGet(token);
if (StringUtils.isNullOrEmpty(partyId)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return JsonUtils.getJsonString(resultObject);
}
try {
String partyid = request.getParameter("partyid");
String type = request.getParameter("type");
String content = request.getParameter("content");
String send_time_stmp = request.getParameter("send_time_stmp");
if (StringUtils.isNullOrEmpty(partyid)) {
throw new BusinessException("暂无用户");
}
if (StringUtils.isNullOrEmpty(content.trim()) || StringUtils.isNullOrEmpty(type)) {
throw new BusinessException("请输入内容");
}
Customer customer = customerService.cacheByUsername(this.tokenService.cacheGet(token));
if (customer != null && customer.getOnline_state() != 1) {
throw new BusinessException("您已下线无法发送消息");
}
// 文字内容乱码处理
content = URLDecoder.decode(content, "utf-8");
String loginUsername = this.tokenService.cacheGet(token);
MessageUser messageUser = onlineChatMessageService.cacheMessageUser(partyid);
if (!loginUsername.equals(messageUser.getTarget_username())) {
throw new BusinessException("该用户已移交");
}
OnlineChatMessage onlineChatMessage = null;
// ip表示游客
if (partyid.indexOf(".") != -1 || partyid.indexOf(":") != -1) {
onlineChatMessage = onlineChatVisitorMessageService.saveSend(partyid, type, "receive", content,
loginUsername);
} else {
onlineChatMessage = onlineChatMessageService.saveSend(partyid, type, "receive", content, loginUsername);
}
Map<String, Object> data = new HashMap<String, Object>();
data.put("send_time_stmp", send_time_stmp);
data.put("chat_id", onlineChatMessage != null ? onlineChatMessage.getId() : null);
data.put("updatetime",
onlineChatMessage != null ? DateUtils.format(onlineChatMessage.getCreateTime(), "MM-dd HH:mm")
: null);
resultObject.setData(data);
} /*catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} */catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 创建新用户消息列表
*/
@RequestMapping(value = action + "create.action", produces="text/html;charset=UTF-8")
public String create(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String uid = request.getParameter("uid");
String token = request.getParameter("token");
Customer customer = customerService.cacheByUsername(this.tokenService.cacheGet(token));
if (customer != null && customer.getOnline_state() != 1) {
throw new BusinessException("您已下线无法接收用户");
}
String loginUsername = this.tokenService.cacheGet(token);
if (uid.indexOf(".") != -1 || uid.indexOf(":") != -1) {// ip表示游客
MessageUser messageUser = onlineChatMessageService.cacheMessageUser(uid);
if (messageUser == null) {// 该ip没有发起聊天
throw new BusinessException("用户不存在");
}
MessageUser user = onlineChatVisitorMessageService.saveCreate(uid, loginUsername);
resultObject.setData(user.getIp());
} else {
MessageUser user = onlineChatMessageService.saveCreate(uid, loginUsername);
resultObject.setData(user.getPartyId());
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 删除聊天
*/
@RequestMapping(value = action + "del.action")
public String del(HttpServletRequest request) {
HttpServletResponse response = this.getResponse();
response.setContentType("application/json;charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String partyid = request.getParameter("partyid");
if (partyid.indexOf(".") != -1 || partyid.indexOf(":") != -1) {// ip表示游客
onlineChatMessageService.deleteByIp(partyid);
} else {
onlineChatMessageService.delete(partyid);
}
} /*catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
}*/ catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 查询未读消息
*/
@RequestMapping(value = action + "unread.action", produces="text/html;charset=UTF-8")
public String unread(HttpServletRequest request) {
String token = request.getParameter("token");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
// 只有admin才有客服
int unreadMsg = onlineChatMessageService.getUnreadMsg(null, "customer", this.tokenService.cacheGet(token));
resultObject.setData(unreadMsg);
} /*catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} */catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 设置用户备注
*/
@RequestMapping(value = action + "resetRemarks.action", produces="text/html;charset=UTF-8")
public String resetRemarks(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String partyid = request.getParameter("partyid");
String remarks = request.getParameter("remarks");
if (partyid.indexOf(".") != -1 || partyid.indexOf(":") != -1) {// ip表示游客
resultObject.setData(onlineChatVisitorMessageService.updateResetRemarks(partyid, remarks));
} else {
resultObject.setData(onlineChatMessageService.updateResetRemarks(partyid, remarks));
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
@RequestMapping(value = action + "getUserInfo.action", produces="text/html;charset=UTF-8")
public String getUserInfo(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String partyid = request.getParameter("partyid");
// ip表示游客
if (partyid.indexOf(".") != -1 || partyid.indexOf(":") != -1) {
resultObject.setData(onlineChatVisitorMessageService.getUserInfo(partyid));
} else {
resultObject.setData(onlineChatMessageService.getUserInfo(partyid));
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
@RequestMapping(value = action + "getChatToken.action")
public String getChatToken(){
ResultObject resultObject = new ResultObject();
try {
Token t = this.tokenService.find(this.getUsername_login());
if (null == t) {
throw new BusinessException("token为空");
}
resultObject.setData(t.getToken());
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("loginuser:{" + this.getUsername_login() + "},error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
@RequestMapping(value = action + "deleteOnlineChatMessage.action")
public String deleteOnlineChatMessage(HttpServletRequest request) {
String token = request.getParameter("token");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return JsonUtils.getJsonString(resultObject);
}
try {
String message_id = request.getParameter("message_id");
onlineChatMessageService.updateMessageDelete(message_id, this.tokenService.cacheGet(token));
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
public ResultObject readSecurityContextFromSession(ResultObject resultObject) {
HttpServletRequest request = this.getRequest();
String token = request.getParameter("token");
if (StringUtils.isNullOrEmpty(token)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return resultObject;
}
String partyId = tokenService.cacheGet(token);
if (StringUtils.isNullOrEmpty(partyId)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return resultObject;
}
return resultObject;
}
}

View File

@@ -0,0 +1,182 @@
package project.web.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.web.BaseAction;
import kernel.web.ResultObject;
import project.onlinechat.MessageUser;
import project.onlinechat.OnlineChatMessage;
import project.onlinechat.OnlineChatMessageService;
import project.onlinechat.OnlineChatVisitorMessageService;
import project.party.PartyService;
import project.party.model.Party;
import project.syspara.SysparaService;
import project.user.token.TokenService;
@RestController
@CrossOrigin
public class NewOnlineChatController extends BaseAction {
private Logger logger = LogManager.getLogger(NewOnlineChatController.class);
@Resource
private OnlineChatMessageService onlineChatMessageService;
@Resource
private OnlineChatVisitorMessageService onlineChatVisitorMessageService;
@Resource
private SysparaService sysparaService;
@Resource
private PartyService partyService;
@Resource
private TokenService tokenService;
public final String action = "api/newOnlinechat";
@RequestMapping(action + "!list.action")
public Object list(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
try {
String message_id = request.getParameter("message_id");
String token = request.getParameter("token");
String selectType = request.getParameter("selectType");//管理后台查看消息记录
String partyId_para = request.getParameter("partyId");//管理后台查看的目标用户
String partyId = tokenService.cacheGet(token);
partyId = StringUtils.isNullOrEmpty(partyId) ? this.getIp() : partyId;
if ("background".equals(selectType)) {//后台管理查看系统聊天时传递参数
partyId=partyId_para;
}
List<OnlineChatMessage> list = onlineChatMessageService.cacheGetList(message_id, 10, partyId, "user");
if (!"background".equals(selectType)) {//后台管理查看系统聊天时,未读数不做变动
// 首页的时候才更新未读数
if (StringUtils.isNullOrEmpty(message_id)) {
MessageUser cacheMessageUser = onlineChatMessageService.cacheMessageUser(partyId);
if (cacheMessageUser != null && cacheMessageUser.getUser_unreadmsg() > 0) {
if (partyId.indexOf(".") != -1) {
onlineChatVisitorMessageService.updateUnread(partyId, "user", "read");
} else {
onlineChatMessageService.updateUnread(partyId, "user", "read");
}
}
}
}
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", list.get(i).getId().toString());
map.put("send_receive", list.get(i).getSend_receive());
String type = list.get(i).getType();
map.put("type", type);
String content = list.get(i).getContent();
/*if ("img".equals(type)) {
content = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + content;
}*/
map.put("content", content);
map.put("targetUsername", list.get(i).getTarget_username());
map.put("createtime", DateUtils.format(list.get(i).getCreateTime(), "yyyy-MM-dd HH:mm"));
map.put("delete_status", list.get(i).getDelete_status());
data.add(map);
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return resultObject;
}
@RequestMapping(action + "!unread.action")
public Object unread(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
try {
int unreadMsg = 0;
String token = request.getParameter("token");
String partyId = tokenService.cacheGet(token);
partyId = StringUtils.isNullOrEmpty(partyId) ? this.getIp() : partyId;
unreadMsg = onlineChatMessageService.getUnreadMsg(partyId, "user", null);
resultObject.setData(unreadMsg);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return resultObject;
}
@RequestMapping(value = action + "!send.action")
public Object send(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
try {
String content = request.getParameter("content");
String type = request.getParameter("type");
String token = request.getParameter("token");
if (StringUtils.isNullOrEmpty(content.trim()) || StringUtils.isNullOrEmpty(type)) {
return resultObject;
}
// content = URLDecoder.decode(content, "utf-8");
content = StringUtils.replacer(new StringBuffer(content));
String loginPartyId = tokenService.cacheGet(token);
if (StringUtils.isNullOrEmpty(loginPartyId)) {
if (checkVisitorIp()) {
return resultObject;
}
onlineChatVisitorMessageService.saveSend(this.getIp(), type, "send", content, null);
} else {
if (checkUserBlack(loginPartyId)) {
return resultObject;
}
onlineChatMessageService.saveSend(loginPartyId, type, "send", content, null);
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("------用户给平台发送消息方法错误,报错消息为:"+e.getMessage());
}
return resultObject;
}
/**
* 检验游客ip是否是黑名单truefalse
*/
private boolean checkVisitorIp() {
String blackMenu = sysparaService.find("online_visitor_black_ip_menu").getValue();
List<String> list = new ArrayList<String>(Arrays.asList(blackMenu.split(",")));
return list.contains(this.getIp());
}
private boolean checkUserBlack(String loginPartyId) {
Party party = partyService.cachePartyBy(loginPartyId, true);
String username = party.getUsername();
String blackMenu = sysparaService.find("online_username_black_menu").getValue();
List<String> list = new ArrayList<String>(Arrays.asList(blackMenu.split(",")));
return list.contains(username);
}
}

View File

@@ -0,0 +1,605 @@
package project.web.api;
import com.alibaba.fastjson.JSONObject;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.JsonUtils;
import kernel.util.StringUtils;
import kernel.web.PageActionSupport;
import kernel.web.ResultObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import project.Constants;
import project.mall.seller.SellerService;
import project.mall.seller.model.Seller;
import project.onlinechat.*;
import project.onlinechat.event.message.ImSendEvent;
import project.party.PartyService;
import project.party.model.Party;
import project.syspara.SysparaService;
import project.user.token.TokenService;
import sun.net.util.IPAddressUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@RestController
@CrossOrigin
public class UserOnlineChatController extends PageActionSupport {
private Logger logger = LogManager.getLogger(UserOnlineChatController.class);
@Resource
private OnlineChatUserMessageService onlineChatUserMessageService;
@Resource
private TokenService tokenService;
@Resource
private PartyService partyService;
@Resource
private SysparaService sysparaService;
@Resource
private SellerService sellerService;
private final String action = "public/userOnlineChatController!";
/**
* 在线聊天-人员列表
*/
@RequestMapping(value = action + "userlist.action", produces = "text/html;charset=UTF-8")
public String userlist(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
if (checkVisitorIp()) {
return JsonUtils.getJsonString(resultObject);
}
try {
int pageno = 1;
if (null != request.getParameter("page_no")) {
pageno = Integer.valueOf(request.getParameter("page_no"));
}
int pageSize = 50;
String token = request.getParameter("token");
String currentLoginType = request.getParameter("loginType");
// 首先要从token中拿到这个用户id当用户的id取不到说明这个是游客
String currentUserPartyId = tokenService.cacheGet(token);
// 得到当前的用户的partId或者IP地址
String currentUserId = StringUtils.isNullOrEmpty(currentUserPartyId) ? this.getIp() : currentUserPartyId;
// 检查当前用户是否在黑名单中
if (checkIfBlack(currentUserId)) {
return JsonUtils.getJsonString(resultObject);
}
// 拿到所有与当前用户相关的会话关系对象
List<ChatUser> chatUsers = onlineChatUserMessageService.cacheGetMessageUserPage(pageno, pageSize, currentUserId,currentLoginType);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
Party currentParty = this.partyService.cachePartyBy(currentUserId, true);
boolean currentIsSellerFlag = (currentParty != null && sellerService.getSeller(currentUserId) != null) ? true : false;
for (int i = 0; i < chatUsers.size(); i++) {
Map<String, Object> map = new HashMap<String, Object>();
ChatUser chatUser = chatUsers.get(i);
map.put("id", chatUser.getId());
String userId = "";
// 拿到与当前登录用户对话的用户,如果当前登录用户是发起会话用户,则要查找的用户为另一个用户,并根据会话用户类别设置未读数
if (chatUser.getStart_id().equals(currentUserId)) {
userId = chatUser.getUser_id();
map.put("unreadmsg", chatUser.getStart_unread());
} else {
userId = chatUser.getStart_id();
map.put("unreadmsg", chatUser.getUser_unread());
}
Party party = this.partyService.cachePartyBy(userId, true);
if (party != null) {//联系人非游客
// 默认显示用户的用户名和头像
map.put("username", party.getUsername());
map.put("useravatar", party.getAvatar());
map.put("uid", party.getUsercode());
map.put("partyid", party.getId().toString());
// 如果联系人为商家,需要返回联系人的商家店铺名和店铺图像
if (party.getRoleType() == 1) {//联系人为商家
Seller seller = sellerService.getSeller(userId);
if (seller != null) {//联系人具有商家和用户双重身份时
// 默认user身份登陆的或者当前用户不具商家身份联系人取商家信息
map.put("username", seller.getName());
map.put("avatar", seller.getAvatar());
if (currentIsSellerFlag && "shop".equals(currentLoginType)) {//当前用户为商家shop身份登陆的 联系人取用户信息
map.put("username", party.getUsername());
map.put("avatar", party.getAvatar());
}
/*if (currentIsSellerFlag && "user".equals(currentLoginType)) {}*///当前用户为商家user身份登陆的 联系人取紧挨着的商户信息
// if(!currentIsSellerFlag){}//当前用户为游客或者用户时候 俩个用户没有一个是商家,没有这样的数据
}
} else {//联系人为用户的情况下
if (currentIsSellerFlag && "user".equals(currentLoginType)) {//当前用户为商家user身份登陆时候排除这个用户
continue;
}
/*if (currentIsSellerFlag && "shop".equals(currentLoginType)) {}*///当前用户为商家shop身份登陆时候按照默认取值
}
} else {//联系人为游客
if (currentIsSellerFlag && "user".equals(currentLoginType)) {//当前用户为商家user身份登陆时候排除这个用户
continue;
}
/*if (currentIsSellerFlag && "shop".equals(currentLoginType)) {}*///当前用户为商家shop身份登陆时正常执行
if(!currentIsSellerFlag){//当前用户为游客或者用户时候 俩个用户没有一个是商家,没有这样的数据
continue;
}
map.put("username", userId);
map.put("partyid", userId);
}
map.put("remarks", chatUser.getRemarks());
List<OnlineChatUserMessage> chats = onlineChatUserMessageService.cacheGetList(currentLoginType,null, 1, chatUser.getChat_id());
String content = "";
Date chatDate = null;
if (chats.size() > 0) {
chatDate = chats.get(0).getCreateTime();
if ("img".equals(chats.get(0).getContentType())) {
content = "[picture]";
} else {
content = chats.get(0).getContent();
}
}
map.put("content", content);
map.put("updatetime",
DateUtils.getISO8601TimestampFromDateStr(chatDate != null ? chatDate : chatUser.getUpdateTime()));
map.put("order_updatetime", chatDate != null && chatDate.after(chatUser.getUpdateTime()) ? chatDate : chatUser.getUpdateTime());// 用作排序
data.add(map);
Collections.sort(data, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> paramT1, Map<String, Object> paramT2) {
Date date1 = (Date) paramT1.get("order_updatetime");
Date date2 = (Date) paramT2.get("order_updatetime");
return -date1.compareTo(date2);
}
});
int start = 0;
int end = start + pageSize;
if (data.size() <= end) {
end = data.size();
}
List<Map<String, Object>> resultData = new ArrayList<Map<String, Object>>();
resultData.addAll(data);
List<Map<String, Object>> subList = resultData.subList(start, end);
resultObject.setData(subList);
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 聊天记录列表
*/
@RequestMapping(value = action + "list.action", produces = "text/html;charset=UTF-8")
public String list(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
if (checkVisitorIp()) {
return JsonUtils.getJsonString(resultObject);
}
try {
String message_id = request.getParameter("message_id");
// 被读取聊天记录的用户的id
String beReadPartyId = request.getParameter("partyid");
// 登录类型
String loginType = request.getParameter("loginType");
// 当前用户的id号
String token = request.getParameter("token");
// 首先要从token中拿到这个用户id当用户的id取不到说明这个是游客
String currentUserPartyId = tokenService.cacheGet(token);
currentUserPartyId = StringUtils.isNullOrEmpty(currentUserPartyId) ? this.getIp() : currentUserPartyId;
// 检查当前用户是否在黑名单
if (checkIfBlack(currentUserPartyId)) {
return JsonUtils.getJsonString(resultObject);
}
if (StringUtils.isNullOrEmpty(beReadPartyId)) {
throw new BusinessException("暂无用户");
}
if (checkDoubleIp(currentUserPartyId, beReadPartyId)) {
throw new BusinessException("游客无与游客的消息记录");
}
String chatId="";
if ("user".equals(loginType)) {
chatId=new StringBuffer().append(currentUserPartyId).append("-").append(beReadPartyId).toString();
}else if ("shop".equals(loginType)){
chatId=new StringBuffer().append(beReadPartyId).append("-").append(currentUserPartyId).toString();
}
List<OnlineChatUserMessage> messages = onlineChatUserMessageService.cacheGetList(loginType,message_id, 30, chatId);
// 首页的时候才更新未读数
if (StringUtils.isNullOrEmpty(message_id) && messages.size() > 0) {
// String chatId = messages.get(0).getChatId();
onlineChatUserMessageService.updateUnread(currentUserPartyId, chatId);
}
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (int i = 0; i < messages.size(); i++) {
OnlineChatUserMessage message = messages.get(i);
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", message.getId().toString());
map.put("send_receive", currentUserPartyId.equals(message.getSendId()) ? "send" : "receive");
String contentType = message.getContentType();
map.put("type", contentType);
String content = message.getContent();
// map.put("content", "img".equals(contentType) ? Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + content : content);
map.put("content", content);
// map.put("createtime", DateUtils.format(message.getCreateTime(), "yyyy-MM-dd HH:mm"));
map.put("createtime",DateUtils.getISO8601TimestampFromDateStr(message.getCreateTime()));
map.put("delete_status", message.getDelete_status());
data.add(map);
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 发送消息
*/
@RequestMapping(value = action + "send.action", produces = "text/html;charset=UTF-8")
public Object send(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
String token = request.getParameter("token");
String sendType = request.getParameter("sendType");
String chatId = request.getParameter("chatId");
// 区分当前用户是商家还是用户
String currentLoginType = request.getParameter("loginType");
String currentUserPartyId = null;
String otherPartyId = null;//
if (StringUtils.isNotEmpty(sendType) && "backendSend".equals(sendType)) {//管理后台发送消息的时候以用户身份发送因此为starId
currentUserPartyId = Arrays.asList(chatId.split("-")).get(0);
otherPartyId = Arrays.asList(chatId.split("-")).get(1);
}else{
currentUserPartyId = tokenService.cacheGet(token);
// 消息消息接收者用户id 有可能是ip也有可能是partyid
otherPartyId = request.getParameter("partyid");
}
if (StringUtils.isNullOrEmpty(currentUserPartyId)) {
if (checkVisitorIp()) {
return resultObject;
}
} else {
if (checkUserBlack(currentUserPartyId)) {
return resultObject;
}
}
currentUserPartyId = StringUtils.isNullOrEmpty(currentUserPartyId) ? this.getIp() : currentUserPartyId;
try {
String type = request.getParameter("type");
String content = request.getParameter("content");
if (StringUtils.isNullOrEmpty(otherPartyId)) {
throw new BusinessException("暂无用户");
}
if (StringUtils.isNullOrEmpty(content.trim()) || StringUtils.isNullOrEmpty(type)) {
throw new BusinessException("请输入内容");
}
// 检测这个partyId从系统中是否可以取到用户如果取不到用户则为游客
Party party = partyService.cachePartyBy(otherPartyId, true);
if (party == null) {
if (IPAddressUtil.isIPv4LiteralAddress(otherPartyId) || IPAddressUtil.isIPv6LiteralAddress(otherPartyId)) {
} else {
throw new BusinessException("系统无该用户或者ip地址不正确");
}
}
if (checkDoubleIp(currentUserPartyId, otherPartyId)) {
throw new BusinessException("游客不能向游客发送消息");
}
content = StringUtils.replacer(new StringBuffer(content));
OnlineChatUserMessage message = null;
if ("shop".equals(currentLoginType)) {
message = onlineChatUserMessageService.saveSend(otherPartyId,currentUserPartyId,type, "receive", content,0,currentLoginType);
}else {
message = onlineChatUserMessageService.saveSend(currentUserPartyId,otherPartyId,type, "send", content,0,currentLoginType);
}
// 发出 spring event 事件,通知消息发送
try {
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
wac.publishEvent(new ImSendEvent(this, message));
} catch (Exception e) {
logger.error("发布IM发送消息事件时报错:", e);
}
Map<String, Object> data = new HashMap<String, Object>();
data.put("updatetime", DateUtils.format(message.getCreateTime(), "yyyy-MM-dd HH:mm"));
data.put("delete_status", message.getDelete_status());
data.put("chat_id", message.getId());
data.put("type", message.getContentType());
data.put("content", message.getContent());
data.put("send_receive", message.getSendId().equals(currentUserPartyId) ? "send" : "receive");
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 当用户从商品进入,用户发起与商家聊天,或者商家从订单进入,商家发起与游客聊天时候,需要发送默认消息
*/
@RequestMapping(value = action + "senddefault.action", produces = "text/html;charset=UTF-8")
public Object sendDefaultMessage(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
String sellerId = request.getParameter("sellerId");
String userId = request.getParameter("userId");
String loginType = request.getParameter("loginType");
String token = request.getParameter("token");
String currentUserPartyId = tokenService.cacheGet(token);
currentUserPartyId = StringUtils.isNullOrEmpty(currentUserPartyId) ? this.getIp() : currentUserPartyId;
OnlineChatUserMessage message = null;
try {
if ("shop".equals(loginType)) {//商家主动从订单进入到与用户聊天时,用户发送默认消息给商家
this.readSecurityContextFromSession(resultObject);
if (Objects.isNull(this.partyService.cachePartyBy(userId,true)) || Objects.isNull(sellerService.getSeller(currentUserPartyId))) {
throw new BusinessException("暂无用户");//没有商家和用户时
}
// 不存在这个会话时候发送默认消息
if (!onlineChatUserMessageService.checkChat(currentUserPartyId,sellerId)) {//发送删除消息
message = onlineChatUserMessageService.saveSend(userId, currentUserPartyId, "text", "send", "",-1,loginType);
}
}
if ("user".equals(loginType)) {//用户进入,商家发送默认消息给用户
if (StringUtils.isNullOrEmpty(sellerId) || sellerService.getSeller(sellerId)==null) {
throw new BusinessException("暂无用户");
}
if (StringUtils.isNullOrEmpty(currentUserPartyId)) {
if (checkVisitorIp()) {//判断ip黑名单
return resultObject;
}
} else {
if (checkUserBlack(currentUserPartyId)) {//用户黑名单
return resultObject;
}
}
// 不存在这个会话时候发送默认消息
if (!onlineChatUserMessageService.checkChat(currentUserPartyId,sellerId)) {
String defaultMessage =Optional.ofNullable(sellerService.getSeller(sellerId).getImInitMessage()).orElse("Hello, welcome!");
String content = StringUtils.replacer(new StringBuffer(defaultMessage));
// 2023-11-07 最新需求 卖家未设置默认消息时,该消息不展示
int messageDeleteType = StringUtils.isEmptyString(sellerService.getSeller(sellerId).getImInitMessage()) ? -1 : 0;
message = onlineChatUserMessageService.saveSend(currentUserPartyId, sellerId,"text", "receive", content,messageDeleteType,"user");
}
}
if (Objects.nonNull(message)) {
JSONObject o =new JSONObject();
o.put("updatetime", DateUtils.format(message.getCreateTime(), "yyyy-MM-dd HH:mm"));
o.put("delete_status", message.getDelete_status());
o.put("chat_id", message.getId());
o.put("type", message.getContentType());
o.put("content", message.getContent());
o.put("send_receive", message.getSendId().equals(currentUserPartyId) ? "send" : "receive");
resultObject.setData(o);
}
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
}catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 查询未读消息
*/
@RequestMapping(action + "unread.action")
public Object unread(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
if (checkVisitorIp()) {
return resultObject;
}
int unreadMsg = 0;
// 2023-04-19 确认用户未读数总数不计平台的未读总数
// int unreadPlatformMsg = 0;
String token = request.getParameter("token");
String loginType = request.getParameter("loginType");
String currentUserId = tokenService.cacheGet(token);
if (StringUtils.isNullOrEmpty(currentUserId)) {
currentUserId = this.getIp();
logger.warn("======> api: userOnlineChatController!unread.action 基于 token:" + token + " 未能提取到 partyId 信息");
}
if (checkIfBlack(currentUserId)) {
return JsonUtils.getJsonString(resultObject);
}
try {
if ("shop".equals(loginType)) {//商家固定为userid栏位
this.readSecurityContextFromSession(resultObject);//首先校验登陆
// if (Objects.isNull(this.partyService.cachePartyBy(currentUserId,true)) || Objects.isNull(sellerService.getSeller(currentUserId))) {
// throw new BusinessException("暂无用户");//校验商家信息
// }登录校验通过后肯定存在用户信息不可再进行卖家身份校验因为买家可以登录卖家端这个时候卖家信息还未生成校验不通过会报错登录一次生成卖家信息后正常这里不校验正常去查查询不到返回0
unreadMsg = onlineChatUserMessageService.getUnreadMsg(currentUserId,"shop");//商家可以查看到所有的消息,联系人默认为用户
}else if ("user".equals(loginType)){//用户身份登录的只取与商家的聊天数
unreadMsg = onlineChatUserMessageService.getUnreadMsg(currentUserId,"user");
}
resultObject.setData(unreadMsg);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return resultObject;
}
/**
* 查询买家未读消息
*/
@RequestMapping(action + "buyunread.action")
public Object buyunread(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
if (checkVisitorIp()) {
return resultObject;
}
String loginPartyId = this.getLoginPartyId();
try {
Map<String, Object> resultMap = onlineChatUserMessageService.getBuyUnreadCount(loginPartyId);
Integer count = Integer.parseInt(String.valueOf(resultMap.get("count")));
resultObject.setData(count);
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return resultObject;
}
/**
* 商家端从订单给用户发起聊天前,检查会话是否存在 0会话不存在 1会话存在
*/
@RequestMapping(value = action + "check.action", produces = "text/html;charset=UTF-8")
public Object checkChat(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
try {
String salePartyId = tokenService.cacheGet(request.getParameter("token"));
if (StringUtils.isNullOrEmpty(salePartyId)) {
throw new BusinessException("token失效,请重新登录");
}
String userPartyId = request.getParameter("partyid");
Party party = partyService.cachePartyBy(userPartyId, true);
if (party == null) {
throw new BusinessException("partyid不正确系统无该用户");
}
Map<String, Object> data = new HashMap<String, Object>();
data.put("flag", "0");
if (this.onlineChatUserMessageService.cacheChatUser(salePartyId + "-" + userPartyId) != null ||
this.onlineChatUserMessageService.cacheChatUser(userPartyId + "-" + salePartyId) != null) {
data.put("flag", "1");
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 管理后台查看对话
*/
@RequestMapping(value = action + "onechat.action", produces = "text/html;charset=UTF-8")
public String oneChats(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
try {
String chatid_para = request.getParameter("chatid");
String messageId = request.getParameter("messageid");
if (StringUtils.isNullOrEmpty(chatid_para)) {
throw new BusinessException("会话id不能为空");
}
ChatUser chatUser = this.onlineChatUserMessageService.cacheChatUser(chatid_para);
String start_id = chatUser.getStart_id();
List<OnlineChatUserMessage> messages = onlineChatUserMessageService.cacheGetList("back",messageId, 30, chatid_para);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
// 首页的时候才更新未读数
if (StringUtils.isNullOrEmpty(messageId) && messages.size() > 0) {
onlineChatUserMessageService.updateUnread(start_id, chatUser.getChat_id());
}
for (int i = 0; i < messages.size(); i++) {
OnlineChatUserMessage message = messages.get(i);
Map<String, Object> map = new HashMap<String, Object>();
map.put("message_id", message.getId().toString());
map.put("send_receive", start_id.equals(message.getSendId()) ? "send" : "receive");
String contentType = message.getContentType();
map.put("type", contentType);
String content = message.getContent();
map.put("content", "img".equals(contentType) ? Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + content : content);
map.put("createtime", DateUtils.format(message.getCreateTime(), "yyyy-MM-dd HH:mm"));
map.put("delete_status", message.getDelete_status());
data.add(map);
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Exception e) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", e);
}
return JsonUtils.getJsonString(resultObject);
}
/**
* 检验游客ip是否是黑名单truefalse
*/
private boolean checkVisitorIp() {
String blackMenu = sysparaService.find("online_visitor_black_ip_menu").getValue();
if (StringUtils.isNullOrEmpty(blackMenu)) {
return false;
}
List<String> list = new ArrayList<String>(Arrays.asList(blackMenu.split(",")));
return list.contains(this.getIp());
}
private boolean checkUserBlack(String loginPartyId) {
String blackMenu = sysparaService.find("online_username_black_menu").getValue();
if (StringUtils.isNullOrEmpty(blackMenu)) {
return false;
}
Party party = partyService.cachePartyBy(loginPartyId, true);
if (party == null) {
return false;
}
String username = party.getUsername();
List<String> list = new ArrayList<String>(Arrays.asList(blackMenu.split(",")));
return list.contains(username);
}
// 检验发送者和接收者是否都是游客
private boolean checkDoubleIp(String partyId1, String partyId2) {
return ((partyId1.contains(".") || partyId1.contains(":"))) && ((partyId2.contains(".") || partyId2.contains(":")));
}
// 检测当前用户是否在黑名单中
private boolean checkIfBlack(String currentPartyId) {
if (!(currentPartyId.contains(".") || currentPartyId.contains(":"))) {
return checkUserBlack(currentPartyId);
}
return false;
}
public ResultObject readSecurityContextFromSession(ResultObject resultObject) {
HttpServletRequest request = this.getRequest();
String token = request.getParameter("token");
if (StringUtils.isNullOrEmpty(token)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return resultObject;
}
String partyId = tokenService.cacheGet(token);
if (StringUtils.isNullOrEmpty(partyId)) {
resultObject.setCode("403");
resultObject.setMsg("请重新登录");
return resultObject;
}
return resultObject;
}
}