1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-06-29 07:11:38 +08:00
This commit is contained in:
Hai Liang Wang 2020-01-04 13:24:44 +08:00
parent f443501938
commit d77b86bfc9
9 changed files with 258 additions and 111 deletions

View File

@ -1023,20 +1023,22 @@ public class IMController extends Handler {
return view;
}
@RequestMapping("/leavemsg/save")
@Menu(type = "admin", subtype = "user")
public ModelAndView leavemsgsave(HttpServletRequest request, @Valid String appid, @Valid LeaveMsg msg) {
if (StringUtils.isNotBlank(appid)) {
SNSAccount snsAccount = snsAccountRepository.findBySnsid(appid);
String orgi = snsAccount.getOrgi();
CousultInvite invite = inviteRepository.findBySnsaccountidAndOrgi(appid, orgi);
List<LeaveMsg> msgList = leaveMsgRes.findByOrgiAndUserid(invite.getOrgi(), msg.getUserid());
// if(msg!=null && msgList.size() == 0){
if (msg != null) {
msg.setOrgi(invite.getOrgi());
leaveMsgRes.save(msg);
}
snsAccountRepository.findBySnsid(appid).ifPresent(p -> {
CousultInvite invite = inviteRepository.findBySnsaccountidAndOrgi(appid, MainContext.SYSTEM_ORGI);
// TODO 增加策略防止恶意刷消息
// List<LeaveMsg> msgList = leaveMsgRes.findByOrgiAndUserid(invite.getOrgi(), msg.getUserid());
// if(msg!=null && msgList.size() == 0){
if (msg != null) {
msg.setOrgi(invite.getOrgi());
msg.setChannel(p);
msg.setSnsId(appid);
leaveMsgRes.save(msg);
}
});
}
return request(super.createRequestPageTempletResponse("/apps/im/leavemsgsave"));
}

View File

@ -27,10 +27,7 @@ import com.chatopera.cc.controller.Handler;
import com.chatopera.cc.model.*;
import com.chatopera.cc.peer.PeerSyncIM;
import com.chatopera.cc.persistence.repository.*;
import com.chatopera.cc.proxy.AgentStatusProxy;
import com.chatopera.cc.proxy.AgentUserProxy;
import com.chatopera.cc.proxy.OnlineUserProxy;
import com.chatopera.cc.proxy.UserProxy;
import com.chatopera.cc.proxy.*;
import com.chatopera.cc.socketio.message.Message;
import com.chatopera.cc.util.IP;
import com.chatopera.cc.util.IPTools;
@ -91,6 +88,9 @@ public class ChatServiceController extends Handler {
@Autowired
private LeaveMsgRepository leaveMsgRes;
@Autowired
private LeaveMsgProxy leaveMsgProxy;
@Autowired
private OrganRepository organRes;
@ -543,10 +543,14 @@ public class ChatServiceController extends Handler {
@RequestMapping("/leavemsg/index")
@Menu(type = "service", subtype = "leavemsg", admin = true)
public ModelAndView leavemsg(ModelMap map, HttpServletRequest request) {
Page<LeaveMsg> leaveMsgList = leaveMsgRes.findByOrgi(
Page<LeaveMsg> leaveMsgs = leaveMsgRes.findByOrgi(
super.getOrgi(request), new PageRequest(super.getP(request), super.getPs(request), Direction.DESC,
"createtime"));
map.put("leaveMsgList", leaveMsgList);
for (final LeaveMsg l : leaveMsgs) {
leaveMsgProxy.resolveChannelBySnsid(l);
}
map.put("leaveMsgList", leaveMsgs);
return request(super.createAppsTempletResponse("/apps/service/leavemsg/index"));
}

View File

@ -31,18 +31,18 @@ public class LeaveMsg {
private String orgi ;
private Date createtime = new Date() ;
private String creater ;
private String name ;
private String mobile ;
private String address ;
private String email ;
private String content ;
private String msgstatus ;
private String qq ;
private String userid ;
private String snsId;
@Transient
private SNSAccount channel;
@Id
@Column(length = 32)
@ -143,4 +143,22 @@ public class LeaveMsg {
public void setUserid(String userid) {
this.userid = userid;
}
@Column(name = "snsid")
public String getSnsId() {
return snsId;
}
public void setSnsId(String snsId) {
this.snsId = snsId;
}
@Transient
public SNSAccount getChannel() {
return channel;
}
public void setChannel(SNSAccount channel) {
this.channel = channel;
}
}

View File

@ -34,7 +34,8 @@ public interface SNSAccountRepository
boolean existsBySnsidAndSnstypeAndOrgi(String snsid, String snsType, String orgi);
SNSAccount findBySnsid(String snsid);
@Query(value = "SELECT * FROM `uk_snsaccount` WHERE snsid = ?1 LIMIT 1", nativeQuery = true)
Optional<SNSAccount> findBySnsid(String snsid);
SNSAccount findBySnsidAndOrgi(String snsid, String orgi);

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2019-2020 Chatopera Inc, <https://www.chatopera.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chatopera.cc.proxy;
import com.chatopera.cc.model.LeaveMsg;
import com.chatopera.cc.model.SNSAccount;
import com.chatopera.cc.persistence.repository.SNSAccountRepository;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LeaveMsgProxy {
private final static Logger logger = LoggerFactory.getLogger(LeaveMsgProxy.class);
@Autowired
private SNSAccountRepository snsAccountRes;
/**
* 根据snsId获得渠道信息
*
* @param leaveMsg
* @return
*/
public boolean resolveChannelBySnsid(final LeaveMsg leaveMsg) {
if (StringUtils.isNotBlank(leaveMsg.getSnsId())) {
snsAccountRes.findBySnsid(leaveMsg.getSnsId()).ifPresent(p -> leaveMsg.setChannel(p));
} else {
leaveMsg.setChannel(new SNSAccount());
}
if (leaveMsg.getChannel() != null && StringUtils.isNotBlank(leaveMsg.getChannel().getName())) {
return true;
} else {
return false;
}
}
}

View File

@ -1,98 +1,127 @@
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<#include "/apps/service/include/left.html">
</div>
<div class="layui-side-scroll">
<#include "/apps/service/include/left.html">
</div>
</div>
<div class="layui-body">
<div class="layui-side-scroll">
<div class="row">
<div class="col-lg-12">
<h1 class="site-h1" style="border-top:1px solid #e6e6e6;">
访客留言<#if leaveMsgList??>${leaveMsgList.totalElements}</#if>
</h1>
<table class="layui-table overflow" lay-skin="line" style="table-layout: fixed; word-break: break-all;">
<thead>
<tr class="design-sortable-tr">
<th>姓名</th>
<th>电话</th>
<th>邮件</th>
<th>地址</th>
<th>QQ</th>
<th width="20%">内容</th>
<th width="80px">留言时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#if leaveMsgList?? && leaveMsgList.content??>
<#list leaveMsgList.content as leaveMsg>
<tr class="tdHasContorllor design-dropable-td">
<td valign="top" class=" first_td_head" title="${leaveMsg.name!''}">
<p>
<a href="javascript:void(0)">
${leaveMsg.name!''}
</a>
</p>
</td>
<td title="${leaveMsg.mobile!''}" valign="top"><p>${leaveMsg.mobile!''}</p></td>
<td title="${leaveMsg.email!''}" valign="top"><p>${leaveMsg.email!''}</p></td>
<td title="${leaveMsg.address!''}" valign="top"><p>${leaveMsg.address!''}</p></td>
<td title="${leaveMsg.qq!''}" valign="top"><p>${leaveMsg.qq!''}</p></td>
<td title="${leaveMsg.content!''}" valign="top" title="${leaveMsg.content!''}"><p>${leaveMsg.content!''}</p></td>
<td valign="top"><#if leaveMsg.createtime??>${leaveMsg.createtime?string('yyyy-MM-dd HH:mm:ss')}</#if></td>
<td valign="top">
<a href="/service/leavemsg/delete.html?id=${leaveMsg.id!''}" data-toggle="tip" title="删除留言不可恢复,请确认是否删除留言?">
<i class="layui-icon">&#x1006;</i>删除
</a>
</td>
</tr>
</#list>
<#else>
<tr>
<td colspan="8" style="height:400px;">
<div class="ukefu-empty" style="background: none">
<i class="layui-icon">&#xe63a;</i>
<div style="">当前没有在线坐席</div>
</div>
</td>
</tr>
</#if>
</tbody>
</table>
<div class="layui-side-scroll">
<div class="row">
<div class="col-lg-12">
<h1 class="site-h1" style="border-top:1px solid #e6e6e6;">
访客留言<#if leaveMsgList??>${leaveMsgList.totalElements}</#if>
</h1>
<table class="layui-table overflow" lay-skin="line" style="table-layout: fixed; word-break: break-all;">
<thead>
<tr class="design-sortable-tr">
<th>渠道</th>
<th>名称</th>
<th>姓名</th>
<th>电话</th>
<th>邮件</th>
<th>地址</th>
<th>QQ</th>
<th width="20%">内容</th>
<th width="80px">留言时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#if leaveMsgList?? && leaveMsgList.content??>
<#list leaveMsgList.content as leaveMsg>
<tr class="tdHasContorllor design-dropable-td">
<td valign="top" class=" first_td_head" title="${leaveMsg.channel.snstype!''}">
<p>
<a href="javascript:void(0)">
<#if leaveMsg.channel.snstype=="webim">
网站
<#elseif leaveMsg.channel.snstype=="phone">
电话
<#elseif leaveMsg.channel.snstype=="skype">
Skype
<#else>
未知
</#if>
</a>
</p>
</td>
<td title="${leaveMsg.channel!''}" valign="top">
<p>${leaveMsg.channel.name!''}</p>
</td>
<td title="${leaveMsg.name!''}" valign="top">
<p>${leaveMsg.name!''}</p>
</td>
<td title="${leaveMsg.mobile!''}" valign="top">
<p>${leaveMsg.mobile!''}</p>
</td>
<td title="${leaveMsg.email!''}" valign="top">
<p>${leaveMsg.email!''}</p>
</td>
<td title="${leaveMsg.address!''}" valign="top">
<p>${leaveMsg.address!''}</p>
</td>
<td title="${leaveMsg.qq!''}" valign="top">
<p>${leaveMsg.qq!''}</p>
</td>
<td title="${leaveMsg.content!''}" valign="top" title="${leaveMsg.content!''}">
<p>${leaveMsg.content!''}</p>
</td>
<td valign="top">
<#if leaveMsg.createtime??>${leaveMsg.createtime?string('yyyy-MM-dd HH:mm:ss')}
</#if>
</td>
<td valign="top">
<a href="/service/leavemsg/delete.html?id=${leaveMsg.id!''}" data-toggle="tip"
title="删除留言不可恢复,请确认是否删除留言?">
<i class="layui-icon">&#x1006;</i>删除
</a>
</td>
</tr>
</#list>
<#else>
<tr>
<td colspan="8" style="height:400px;">
<div class="ukefu-empty" style="background: none">
<i class="layui-icon">&#xe63a;</i>
<div style="">当前没有在线坐席</div>
</div>
</td>
</tr>
</#if>
</tbody>
</table>
</div>
</div>
<div class="row" style="padding:5px;">
<div class="col-lg-12" id="page" style="text-align:center;"></div>
</div>
</div>
</div>
</div>
<div class="row" style="padding:5px;">
<div class="col-lg-12" id="page" style="text-align:center;"></div>
</div>
</div>
</div>
<style>
.overflow td p{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
.overflow td p {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
</style>
<script>
layui.use(['laypage', 'layer'], function(){
var laypage = layui.laypage
,layer = layui.layer;
layui.use(['laypage', 'layer'], function () {
var laypage = layui.laypage
, layer = layui.layer;
laypage({
cont: 'page'
,pages: <#if leaveMsgList??>${leaveMsgList.totalPages}<#else>0</#if> //总页数
,curr:<#if leaveMsgList??>${leaveMsgList.number+1}<#else>0</#if>
,groups: 5 //连续显示分页数
,jump:function(data , first){
if(!first){
location.href = "/service/leavemsg/index.html?p="+data.curr ;
}
}
});
laypage({
cont: 'page'
, pages: <#if leaveMsgList ??> ${ leaveMsgList.totalPages } <#else> 0</#if> //总页数
, curr:<#if leaveMsgList ??> ${ leaveMsgList.number + 1 }<#else> 0</#if>
, groups: 5 //连续显示分页数
, jump: function(data, first) {
if (!first) {
location.href = "/service/leavemsg/index.html?p=" + data.curr;
}
}
});
});
</script>

View File

@ -2356,6 +2356,7 @@ CREATE TABLE `uk_leavemsg` (
`msgstatus` varchar(20) DEFAULT NULL COMMENT '消息状态',
`contactsid` varchar(32) DEFAULT NULL COMMENT '匹配联系人ID',
`userid` varchar(32) DEFAULT NULL COMMENT '用户ID',
`snsid` varchar(32) DEFAULT NULL COMMENT '渠道snsid',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='留言信息表';
@ -3483,10 +3484,11 @@ CREATE TABLE `uk_snsaccount` (
`qrcode` varchar(100) DEFAULT NULL COMMENT '二维码',
`refreshtoken` varchar(255) DEFAULT NULL COMMENT '刷新token',
`verify` varchar(255) DEFAULT NULL COMMENT '验证代码',
`snsid` varchar(32) DEFAULT NULL COMMENT 'SNSID',
`snsid` varchar(32) NOT NULL COMMENT 'SNSID',
`agent` tinyint(4) DEFAULT NULL COMMENT '坐席',
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `SQL121227155530370` (`ID`) USING BTREE
UNIQUE KEY `SQL121227155530370` (`ID`) USING BTREE,
UNIQUE KEY (`snsid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='渠道配置表';
-- ----------------------------

View File

@ -0,0 +1,32 @@
USE `cosinee`;
-- -----------------
-- prepare variables
-- -----------------
SET @dbname = DATABASE ( );
SET @tablename = "uk_leavemsg";
SET @columnname = "snsid";
SET @preparedStatement = (
SELECT
IF
(
(
SELECT
COUNT( * )
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
( table_name = @tablename )
AND ( table_schema = @dbname )
AND ( column_name = @columnname )
) > 0,
"SELECT 1",
CONCAT( "ALTER TABLE ", @tablename, " ADD ", @columnname, " varchar(32) DEFAULT NULL COMMENT '渠道snsid';" )
)
);
PREPARE alterIfNotExists
FROM
@preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;

View File

@ -0,0 +1,6 @@
USE `cosinee`;
-- -----------------
-- set snsid as unique
-- -----------------
ALTER TABLE `uk_snsaccount` ADD UNIQUE (`snsid`);