mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-01 16:38:02 +08:00
Merge branch 'develop' of github.com:chatopera/cosin into develop
This commit is contained in:
commit
639d6c5d73
@ -34,6 +34,8 @@
|
||||
|
||||
## 产品演示
|
||||
|
||||
* 坐席工作台
|
||||
|
||||
[http://cc.chatopera.com/](http://cc.chatopera.com/)
|
||||
|
||||
|
||||
@ -42,6 +44,10 @@
|
||||
| admin | admin1234 |
|
||||
|
||||
|
||||
* 网页端访客程序
|
||||
|
||||
[http://cc.chatopera.com/testclient.html](http://cc.chatopera.com/testclient.html)
|
||||
|
||||
## 功能
|
||||
|
||||
* 账号及组织机构管理:按组织、角色分配账号权限
|
||||
|
@ -0,0 +1,2 @@
|
||||
./app/target/
|
||||
./logs/
|
@ -1,6 +1,11 @@
|
||||
FROM chatopera/java:1.0.0
|
||||
MAINTAINER Hai Liang Wang <hain@chatopera.com>
|
||||
|
||||
ARG VCS_REF
|
||||
|
||||
LABEL org.label-schema.vcs-ref=$VCS_REF \
|
||||
org.label-schema.vcs-url="https://github.com/chatopera/cosin"
|
||||
|
||||
# Set timezone
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y tzdata && \
|
||||
@ -26,10 +31,11 @@ RUN /bin/bash -c "mkdir -p /{data,logs}"
|
||||
# build WAR
|
||||
COPY _m2/settings.xml /root/.m2/settings.xml
|
||||
COPY app /app
|
||||
COPY config /config
|
||||
WORKDIR /app
|
||||
RUN mvn clean package && \
|
||||
rm -rf /opt/apache-tomcat/webapps/ROOT && \
|
||||
cp target/contact-center-3.9.0.war /opt/apache-tomcat/webapps/ROOT.war && \
|
||||
cp target/contact-center-*.war.original /opt/apache-tomcat/webapps/ROOT.war && \
|
||||
rm -rf /app && \
|
||||
rm -rf /root/.m2
|
||||
|
||||
|
@ -136,11 +136,6 @@ under the License.
|
||||
</server>
|
||||
-->
|
||||
|
||||
<server>
|
||||
<id>chatopera</id>
|
||||
<username>ada</username>
|
||||
<password>L1OBFepgSZ</password>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
<mirrors>
|
||||
|
@ -13,7 +13,7 @@ PACKAGE_VERSION=1.0.0
|
||||
|
||||
# main
|
||||
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
|
||||
set -x
|
||||
cd $appHome
|
||||
|
||||
docker build --force-rm=true --tag $imagename:$PACKAGE_VERSION .
|
||||
docker build --build-arg VCS_REF=`git rev-parse --short HEAD` --force-rm=true --tag $imagename:$PACKAGE_VERSION .
|
||||
docker tag $imagename:$PACKAGE_VERSION $imagename:develop
|
||||
|
@ -159,9 +159,9 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast</artifactId>
|
||||
<version>3.8</version>
|
||||
<!--$NO-MVN-MAN-VER$-->
|
||||
<artifactId>hazelcast-all</artifactId>
|
||||
<version>3.10.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
@ -346,6 +346,14 @@
|
||||
<attachClasses>true</attachClasses>
|
||||
<warSourceExcludes>**/WEB-INF</warSourceExcludes>
|
||||
<packagingExcludes>**/WEB-INF,**/resources</packagingExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>../config/sql/</directory>
|
||||
<includes>
|
||||
<include>cskefu-MySQL-slim.sql</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<version>2.1.1</version>
|
||||
</plugin>
|
||||
@ -360,23 +368,6 @@
|
||||
</plugins>
|
||||
<defaultGoal>compile</defaultGoal>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>SPRING-LIBS-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>mvn_repository</id>
|
||||
<name>MVNREPOSITORY</name>
|
||||
<url>http://repo1.maven.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>SPRING-LIBS-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>hain</id>
|
||||
@ -384,7 +375,7 @@
|
||||
<email>hailiang.hl.wang@gmail.com</email>
|
||||
<url>https://github.com/Samurais</url>
|
||||
<organization>Chatopera Inc.</organization>
|
||||
<organizationUrl>http://www.chatopera.com</organizationUrl>
|
||||
<organizationUrl>https://www.chatopera.com</organizationUrl>
|
||||
<roles>
|
||||
<role>architect</role>
|
||||
<role>developer</role>
|
||||
|
@ -17,8 +17,11 @@
|
||||
package com.chatopera.cc.app;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.util.mobile.MobileNumberUtils;
|
||||
import com.chatopera.cc.app.config.StartedEventListener;
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.chatopera.cc.util.SystemEnvHelper;
|
||||
import com.chatopera.cc.util.mobile.MobileNumberUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -33,6 +36,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
import java.io.IOException;
|
||||
@ -41,9 +45,8 @@ import java.io.IOException;
|
||||
@EnableJpaRepositories("com.chatopera.cc.app.persistence.repository")
|
||||
@EnableElasticsearchRepositories("com.chatopera.cc.app.persistence.es")
|
||||
@EnableAsync
|
||||
@EnableTransactionManagement
|
||||
public class Application {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
||||
|
||||
|
||||
@Value("${web.upload-path}")
|
||||
private String uploaddir;
|
||||
@ -51,14 +54,32 @@ public class Application {
|
||||
@Value("${spring.servlet.multipart.max-file-size}")
|
||||
private String multipartMaxUpload;
|
||||
|
||||
|
||||
@Value("${spring.servlet.multipart.max-request-size}")
|
||||
private String multipartMaxRequest;
|
||||
|
||||
/**
|
||||
* 记载模块
|
||||
*/
|
||||
// 外呼模块
|
||||
private final static boolean isCalloutModule = SystemEnvHelper.parseModuleFlag("CSKEFU_MODULE_CALLOUT");
|
||||
// CRM模块
|
||||
private final static boolean isContactsModule = SystemEnvHelper.parseModuleFlag("CSKEFU_MODULE_CONTACTS");
|
||||
// 聊天机器人模块
|
||||
private final static boolean isChatbotModule = SystemEnvHelper.parseModuleFlag("CSKEFU_MODULE_CHATBOT");
|
||||
|
||||
static {
|
||||
MainContext.model.put("contacts", true) ;
|
||||
MainContext.model.put("sales", true);
|
||||
MainContext.model.put("chatbot", true);
|
||||
// 外呼模块
|
||||
if (isCalloutModule) {
|
||||
MainContext.model.put(Constants.CSKEFU_MODULE_CALLOUT, true);
|
||||
}
|
||||
// CRM模块
|
||||
if (isContactsModule) {
|
||||
MainContext.model.put(Constants.CSKEFU_MODULE_CONTACTS, true);
|
||||
}
|
||||
// 聊天机器人模块
|
||||
if (isChatbotModule) {
|
||||
MainContext.model.put(Constants.CSKEFU_MODULE_CHATBOT, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,10 +87,10 @@ public class Application {
|
||||
*/
|
||||
protected static void init() {
|
||||
try {
|
||||
logger.info("init mobile number utils ...");
|
||||
System.out.println("init mobile number utils ...");
|
||||
MobileNumberUtils.init();
|
||||
} catch (IOException e) {
|
||||
logger.error("init error ", e);
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,15 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.algorithm;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.aggregation.filter.AgentStatusBusyOrgiFilter;
|
||||
import com.chatopera.cc.aggregation.filter.AgentStatusOrgiFilter;
|
||||
import com.chatopera.cc.aggregation.filter.AgentUserOrgiFilter;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.WebIMReport;
|
||||
import com.corundumstudio.socketio.SocketIONamespace;
|
||||
@ -72,7 +72,6 @@ public class AutomaticServiceDist {
|
||||
/**
|
||||
* 载入坐席 ACD策略配置
|
||||
*
|
||||
* @param orgi
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -141,9 +140,9 @@ public class AutomaticServiceDist {
|
||||
int queneUsers = 0;
|
||||
|
||||
PagingPredicate<String, AgentUser> pagingPredicate = null;
|
||||
if (!StringUtils.isBlank(skill)) {
|
||||
if (StringUtils.isNotBlank(skill)) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentUser>(new SqlPredicate("status = 'inquene' AND skill = '" + skill + "' AND orgi = '" + orgi + "'"), 100);
|
||||
} else if (!StringUtils.isBlank(agent)) {
|
||||
} else if (StringUtils.isNotBlank(agent)) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentUser>(new SqlPredicate("status = 'inquene' AND agent = '" + agent + "' AND orgi = '" + orgi + "'"), 100);
|
||||
} else {
|
||||
pagingPredicate = new PagingPredicate<String, AgentUser>(new SqlPredicate("status = 'inquene' AND orgi = '" + orgi + "'"), 100);
|
||||
@ -168,7 +167,7 @@ public class AutomaticServiceDist {
|
||||
public static List<AgentStatus> getAgentStatus(String skill, String orgi) {
|
||||
PagingPredicate<String, AgentStatus> pagingPredicate = new PagingPredicate<String, AgentStatus>(new SqlPredicate("orgi = '" + orgi + "'"), 100);
|
||||
|
||||
if (!StringUtils.isBlank(skill)) {
|
||||
if (StringUtils.isNotBlank(skill)) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentStatus>(new SqlPredicate("skill = '" + skill + "' AND orgi = '" + orgi + "'"), 100);
|
||||
}
|
||||
List<AgentStatus> agentList = new ArrayList<AgentStatus>();
|
||||
@ -186,7 +185,7 @@ public class AutomaticServiceDist {
|
||||
AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentno, orgi);
|
||||
List<AgentUser> agentStatusList = new ArrayList<AgentUser>();
|
||||
PagingPredicate<String, AgentUser> pagingPredicate = null;
|
||||
if (agentStatus != null && !StringUtils.isBlank(agentStatus.getSkill())) {
|
||||
if (agentStatus != null && StringUtils.isNotBlank(agentStatus.getSkill())) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentUser>(new SqlPredicate("status = 'inquene' AND ((agent = null AND skill = null) OR (skill = '" + agentStatus.getSkill() + "' AND agent = null) OR agent = '" + agentno + "') AND orgi = '" + orgi + "'"), 10);
|
||||
} else {
|
||||
pagingPredicate = new PagingPredicate<String, AgentUser>(new SqlPredicate("status = 'inquene' AND ((agent = null AND skill = null) OR agent = '" + agentno + "') AND orgi = '" + orgi + "'"), 10);
|
||||
@ -207,15 +206,15 @@ public class AutomaticServiceDist {
|
||||
outMessage.setNickName(agentStatus.getUsername());
|
||||
outMessage.setCreatetime(MainUtils.dateFormate.format(new Date()));
|
||||
|
||||
if (!StringUtils.isBlank(agentUser.getUserid())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getUserid())) {
|
||||
OutMessageRouter router = null;
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
if (router != null) {
|
||||
router.handler(agentUser.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage);
|
||||
}
|
||||
}
|
||||
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
// TODO #111 为坐席分配访客
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
@ -269,7 +268,7 @@ public class AutomaticServiceDist {
|
||||
final boolean isPhone = MainContext.ChannelTypeEnum.PHONE.toString().equals(agentUser.getChannel());
|
||||
AgentServiceRepository agentServiceRes = MainContext.getContext().getBean(AgentServiceRepository.class);
|
||||
AgentService service = null;
|
||||
if (!StringUtils.isBlank(agentUser.getAgentserviceid())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
service = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), agentUser.getOrgi());
|
||||
}
|
||||
if (service == null) {//当做留言处理
|
||||
@ -311,7 +310,8 @@ public class AutomaticServiceDist {
|
||||
NettyClients.getInstance().sendCalloutEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser);
|
||||
} else {
|
||||
if (agentStatus != null) // WebIM 查看用户状态
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser);
|
||||
// TODO #111 结束会话
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser);
|
||||
OutMessageRouter router = null;
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
if (router != null) {
|
||||
@ -392,7 +392,7 @@ public class AutomaticServiceDist {
|
||||
public static void recordAgentStatus(String agent, String username, String extno, String skill, boolean admin, String userid, String status, String current, String worktype, String orgi, Date lasttime) {
|
||||
WorkMonitorRepository workMonitorRes = MainContext.getContext().getBean(WorkMonitorRepository.class);
|
||||
WorkMonitor workMonitor = new WorkMonitor();
|
||||
if (!StringUtils.isBlank(agent) && !StringUtils.isBlank(status)) {
|
||||
if (StringUtils.isNotBlank(agent) && StringUtils.isNotBlank(status)) {
|
||||
workMonitor.setAgent(agent);
|
||||
workMonitor.setAgentno(agent);
|
||||
workMonitor.setStatus(status);
|
||||
@ -450,9 +450,9 @@ public class AutomaticServiceDist {
|
||||
/**
|
||||
* 处理ACD 的 技能组请求和 坐席请求
|
||||
*/
|
||||
if (!StringUtils.isBlank(agentUser.getAgent())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getAgent())) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentStatus>(new SqlPredicate(" busy = false AND agentno = '" + agentUser.getAgent() + "' AND orgi = '" + orgi + "'"), 1);
|
||||
} else if (!StringUtils.isBlank(agentUser.getSkill())) {
|
||||
} else if (StringUtils.isNotBlank(agentUser.getSkill())) {
|
||||
pagingPredicate = new PagingPredicate<String, AgentStatus>(new SqlPredicate(" busy = false AND skill = '" + agentUser.getSkill() + "' AND orgi = '" + orgi + "'"), 1);
|
||||
} else {
|
||||
pagingPredicate = new PagingPredicate<String, AgentStatus>(new SqlPredicate(" busy = false AND orgi = '" + orgi + "'"), 1);
|
||||
@ -500,7 +500,8 @@ public class AutomaticServiceDist {
|
||||
if (agentStatus != null) {
|
||||
agentService = processAgentService(agentStatus, agentUser, orgi);
|
||||
publishMessage(orgi, "invite", "success", agentno);
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
// TODO #111 为坐席分配邀请的访客
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
} else {
|
||||
agentService = allotAgent(agentUser, orgi);
|
||||
}
|
||||
@ -528,7 +529,7 @@ public class AutomaticServiceDist {
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static AgentService processChatbotService(final AgentUser agentUser, final String orgi) {
|
||||
public static AgentService processChatbotService(final String botName, final AgentUser agentUser, final String orgi) {
|
||||
AgentService agentService = new AgentService(); //放入缓存的对象
|
||||
AgentServiceRepository agentServiceRes = MainContext.getContext().getBean(AgentServiceRepository.class);
|
||||
Date now = new Date();
|
||||
@ -548,6 +549,8 @@ public class AutomaticServiceDist {
|
||||
agentService.setRegion(agentUser.getRegion());
|
||||
agentService.setUsername(agentUser.getUsername());
|
||||
agentService.setChannel(agentUser.getChannel());
|
||||
if (botName != null)
|
||||
agentService.setAgentusername(botName);
|
||||
|
||||
if (StringUtils.isNotBlank(agentUser.getContextid())) {
|
||||
agentService.setContextid(agentUser.getContextid());
|
||||
@ -579,7 +582,7 @@ public class AutomaticServiceDist {
|
||||
*/
|
||||
private static AgentService processAgentService(AgentStatus agentStatus, AgentUser agentUser, String orgi, boolean finished) throws Exception {
|
||||
AgentService agentService = new AgentService(); //放入缓存的对象
|
||||
if (!StringUtils.isBlank(agentUser.getAgentserviceid())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
agentService.setId(agentUser.getAgentserviceid());
|
||||
}
|
||||
agentService.setOrgi(orgi);
|
||||
@ -668,20 +671,20 @@ public class AutomaticServiceDist {
|
||||
|
||||
AgentServiceRepository agentServiceRes = MainContext.getContext().getBean(AgentServiceRepository.class);
|
||||
|
||||
if (!StringUtils.isBlank(agentUser.getName())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getName())) {
|
||||
agentService.setName(agentUser.getName());
|
||||
}
|
||||
if (!StringUtils.isBlank(agentUser.getPhone())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getPhone())) {
|
||||
agentService.setPhone(agentUser.getPhone());
|
||||
}
|
||||
if (!StringUtils.isBlank(agentUser.getEmail())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getEmail())) {
|
||||
agentService.setEmail(agentUser.getEmail());
|
||||
}
|
||||
if (!StringUtils.isBlank(agentUser.getResion())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getResion())) {
|
||||
agentService.setResion(agentUser.getResion());
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(agentUser.getSkill())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getSkill())) {
|
||||
agentService.setAgentskill(agentUser.getSkill());
|
||||
} else if (agentStatus != null) {
|
||||
agentService.setAgentskill(agentStatus.getSkill());
|
||||
@ -743,7 +746,7 @@ public class AutomaticServiceDist {
|
||||
agentUser.getStatus())) {
|
||||
serviceFinish(agentUser, orgi);
|
||||
}
|
||||
if (!StringUtils.isBlank(agentUser.getId())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getId())) {
|
||||
AgentUserRepository agentUserRes = MainContext.getContext().getBean(AgentUserRepository.class);
|
||||
agentUser = agentUserRes.findByIdAndOrgi(agentUser.getId(), orgi);
|
||||
if (agentUser != null) {
|
||||
@ -766,7 +769,7 @@ public class AutomaticServiceDist {
|
||||
}
|
||||
SessionConfig sessionConfig = initSessionConfig(orgi);
|
||||
String successMsg = "坐席分配成功," + queneTip + "为您服务。";
|
||||
if (!StringUtils.isBlank(sessionConfig.getSuccessmsg())) {
|
||||
if (StringUtils.isNotBlank(sessionConfig.getSuccessmsg())) {
|
||||
successMsg = sessionConfig.getSuccessmsg().replaceAll("\\{agent\\}", queneTip);
|
||||
}
|
||||
return successMsg;
|
||||
@ -779,7 +782,7 @@ public class AutomaticServiceDist {
|
||||
public static String getServiceFinishMessage(String channel, String orgi) {
|
||||
SessionConfig sessionConfig = initSessionConfig(orgi);
|
||||
String queneTip = "坐席已断开和您的对话";
|
||||
if (!StringUtils.isBlank(sessionConfig.getFinessmsg())) {
|
||||
if (StringUtils.isNotBlank(sessionConfig.getFinessmsg())) {
|
||||
queneTip = sessionConfig.getFinessmsg();
|
||||
}
|
||||
return queneTip;
|
||||
@ -795,7 +798,7 @@ public class AutomaticServiceDist {
|
||||
}
|
||||
SessionConfig sessionConfig = initSessionConfig(orgi);
|
||||
String noAgentTipMsg = "坐席全忙,已进入等待队列,您也可以在其他时间再来咨询。";
|
||||
if (!StringUtils.isBlank(sessionConfig.getNoagentmsg())) {
|
||||
if (StringUtils.isNotBlank(sessionConfig.getNoagentmsg())) {
|
||||
noAgentTipMsg = sessionConfig.getNoagentmsg().replaceAll("\\{num\\}", queneTip);
|
||||
}
|
||||
return noAgentTipMsg;
|
||||
@ -809,7 +812,7 @@ public class AutomaticServiceDist {
|
||||
}
|
||||
SessionConfig sessionConfig = initSessionConfig(orgi);
|
||||
String agentBusyTipMsg = "正在排队,请稍候,在您之前,还有 " + queneTip + " 位等待用户。";
|
||||
if (!StringUtils.isBlank(sessionConfig.getAgentbusymsg())) {
|
||||
if (StringUtils.isNotBlank(sessionConfig.getAgentbusymsg())) {
|
||||
agentBusyTipMsg = sessionConfig.getAgentbusymsg().replaceAll("\\{num\\}", queneTip);
|
||||
}
|
||||
return agentBusyTipMsg;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package com.chatopera.cc.app.basic;
|
||||
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.chatopera.cc.util.DateConverter;
|
||||
import com.chatopera.cc.app.basic.resource.ActivityResource;
|
||||
import com.chatopera.cc.app.basic.resource.BatchResource;
|
||||
@ -986,4 +987,13 @@ public class MainContext {
|
||||
public static Class<?> getResource(String resource) {
|
||||
return uKeFuResourceMap.get(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否开启外呼模块
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEnableCalloutModule() {
|
||||
return model.containsKey(Constants.CSKEFU_MODULE_CALLOUT) && (model.get(Constants.CSKEFU_MODULE_CALLOUT).equals(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -766,14 +766,14 @@ public class MainUtils {
|
||||
return workintTime;
|
||||
}
|
||||
|
||||
public static File processImage(File destFile, File imageFile) throws FileNotFoundException, IOException {
|
||||
public static File processImage(final File destFile, final File imageFile) throws FileNotFoundException, IOException {
|
||||
if (imageFile != null && imageFile.exists()) {
|
||||
Thumbnails.of(imageFile).width(460).keepAspectRatio(true).toFile(destFile);
|
||||
}
|
||||
return destFile;
|
||||
}
|
||||
|
||||
public static File scaleImage(File destFile, File imageFile, float quality) throws FileNotFoundException, IOException {
|
||||
public static File scaleImage(final File destFile, final File imageFile, float quality) throws FileNotFoundException, IOException {
|
||||
if (imageFile != null && imageFile.exists()) {
|
||||
Thumbnails.of(imageFile).scale(1f).outputQuality(quality).toFile(destFile);
|
||||
}
|
||||
@ -846,45 +846,6 @@ public class MainUtils {
|
||||
return execute;
|
||||
}
|
||||
|
||||
public static void processAttachmentFile(MultipartFile[] files, AttachmentRepository attachementRes, String path, User user, String orgi, WorkOrders workOrders, HttpServletRequest request, String dataid, String modelid) throws IOException {
|
||||
if (files != null && files.length > 0) {
|
||||
workOrders.setAnonymous(true);//变更用途为是否有 附件
|
||||
//保存附件
|
||||
for (MultipartFile file : files) {
|
||||
if (file.getSize() > 0) { //文件尺寸 限制 ?在 启动 配置中 设置 的最大值,其他地方不做限制
|
||||
String fileid = MainUtils.md5(file.getBytes()); //使用 文件的 MD5作为 ID,避免重复上传大文件
|
||||
if (!StringUtils.isBlank(fileid)) {
|
||||
AttachmentFile attachmentFile = new AttachmentFile();
|
||||
attachmentFile.setCreater(user.getId());
|
||||
attachmentFile.setOrgi(orgi);
|
||||
attachmentFile.setOrgan(user.getOrgan());
|
||||
attachmentFile.setDataid(dataid);
|
||||
attachmentFile.setModelid(modelid);
|
||||
attachmentFile.setModel(MainContext.ModelType.WORKORDERS.toString());
|
||||
attachmentFile.setFilelength((int) file.getSize());
|
||||
if (file.getContentType() != null && file.getContentType().length() > 255) {
|
||||
attachmentFile.setFiletype(file.getContentType().substring(0, 255));
|
||||
} else {
|
||||
attachmentFile.setFiletype(file.getContentType());
|
||||
}
|
||||
if (file.getOriginalFilename() != null && file.getOriginalFilename().length() > 255) {
|
||||
attachmentFile.setTitle(file.getOriginalFilename().substring(0, 255));
|
||||
} else {
|
||||
attachmentFile.setTitle(file.getOriginalFilename());
|
||||
}
|
||||
if (!StringUtils.isBlank(attachmentFile.getFiletype()) && attachmentFile.getFiletype().indexOf("image") >= 0) {
|
||||
attachmentFile.setImage(true);
|
||||
}
|
||||
attachmentFile.setFileid(fileid);
|
||||
attachementRes.save(attachmentFile);
|
||||
FileUtils.writeByteArrayToFile(new File(path, "app/workorders/" + fileid), file.getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置
|
||||
*
|
||||
|
@ -87,7 +87,7 @@ public class IMServerConfiguration
|
||||
FileInputStream in = new FileInputStream(sslFile);
|
||||
sslProperties.load(in);
|
||||
in.close();
|
||||
if(!StringUtils.isBlank(sslProperties.getProperty("key-store")) && !StringUtils.isBlank(sslProperties.getProperty("key-store-password"))){
|
||||
if(StringUtils.isNotBlank(sslProperties.getProperty("key-store")) && StringUtils.isNotBlank(sslProperties.getProperty("key-store-password"))){
|
||||
config.setKeyStorePassword(MainUtils.decryption(sslProperties.getProperty("key-store-password")));
|
||||
InputStream stream = new FileInputStream(new File(path , "ssl/"+sslProperties.getProperty("key-store")));
|
||||
config.setKeyStore(stream);
|
||||
@ -96,7 +96,7 @@ public class IMServerConfiguration
|
||||
|
||||
|
||||
// config.setSSLProtocol("https");
|
||||
int workThreads = !StringUtils.isBlank(threads) && threads.matches("[\\d]{1,6}") ? Integer.parseInt(threads) : 100 ;
|
||||
int workThreads = StringUtils.isNotBlank(threads) && threads.matches("[\\d]{1,6}") ? Integer.parseInt(threads) : 100 ;
|
||||
config.setWorkerThreads(workThreads);
|
||||
// config.setStoreFactory(new HazelcastStoreFactory());
|
||||
config.setAuthorizationListener(new AuthorizationListener() {
|
||||
|
@ -15,8 +15,10 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.config;
|
||||
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.chatopera.cc.app.schedule.CallOutWireTask;
|
||||
import com.chatopera.cc.app.schedule.WebIMAgentDispatcher;
|
||||
import com.chatopera.cc.app.schedule.WebIMOnlineUserDispatcher;
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -38,17 +40,25 @@ public class RedisConfigure {
|
||||
@Autowired
|
||||
CallOutWireTask callOutWireTask;
|
||||
|
||||
@Autowired
|
||||
WebIMAgentDispatcher webIMAgentDispatcher;
|
||||
|
||||
@Autowired
|
||||
WebIMOnlineUserDispatcher webIMOnlineUserDispatcher;
|
||||
|
||||
@Bean
|
||||
RedisMessageListenerContainer redisContainer() {
|
||||
final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(jedisConnectionFactory);
|
||||
container.addMessageListener(messageListener(), pbxEvents());
|
||||
container.addMessageListener(pbxMessageListener(), pbxEvents());
|
||||
container.addMessageListener(imAgentDispatchListener(), imAgentEvents());
|
||||
container.addMessageListener(imOnlineUserDispatchListener(), imOnlineUserEvents());
|
||||
container.setTaskExecutor(Executors.newFixedThreadPool(50));
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
MessageListenerAdapter messageListener() {
|
||||
MessageListenerAdapter pbxMessageListener() {
|
||||
return new MessageListenerAdapter(callOutWireTask);
|
||||
}
|
||||
|
||||
@ -57,4 +67,25 @@ public class RedisConfigure {
|
||||
return new PatternTopic(Constants.FS_CHANNEL_FS_TO_CC);
|
||||
}
|
||||
|
||||
@Bean
|
||||
MessageListenerAdapter imAgentDispatchListener() {
|
||||
return new MessageListenerAdapter(webIMAgentDispatcher);
|
||||
}
|
||||
|
||||
@Bean
|
||||
PatternTopic imAgentEvents() {
|
||||
return new PatternTopic(Constants.INSTANT_MESSAGING_WEBIM_AGENT_CHANNEL);
|
||||
}
|
||||
|
||||
@Bean
|
||||
MessageListenerAdapter imOnlineUserDispatchListener(){
|
||||
return new MessageListenerAdapter(webIMOnlineUserDispatcher);
|
||||
}
|
||||
|
||||
@Bean
|
||||
PatternTopic imOnlineUserEvents() {
|
||||
return new PatternTopic(Constants.INSTANT_MESSAGING_WEBIM_ONLINE_USER_CHANNEL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -57,14 +57,18 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
RequestMatcher beans = new AntPathRequestMatcher("/beans/**");
|
||||
RequestMatcher dump = new AntPathRequestMatcher("/dump/**");
|
||||
RequestMatcher env = new AntPathRequestMatcher("/env/**");
|
||||
RequestMatcher health = new AntPathRequestMatcher("/health/**");
|
||||
RequestMatcher info = new AntPathRequestMatcher("/info/**");
|
||||
RequestMatcher mappings = new AntPathRequestMatcher("/mappings/**");
|
||||
RequestMatcher metrics = new AntPathRequestMatcher("/metrics/**");
|
||||
RequestMatcher trace = new AntPathRequestMatcher("/trace/**");
|
||||
RequestMatcher druid = new AntPathRequestMatcher("/druid/**");
|
||||
|
||||
return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , health , info , mappings , metrics , trace, druid);
|
||||
/**
|
||||
* Bypass actuator api
|
||||
*/
|
||||
// RequestMatcher health = new AntPathRequestMatcher("/health/**");
|
||||
// RequestMatcher metrics = new AntPathRequestMatcher("/metrics/**");
|
||||
// return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , health , info , mappings , metrics , trace, druid);
|
||||
return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , mappings , trace, druid);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -39,7 +39,7 @@ public class ApplicationController extends Handler{
|
||||
view.addObject("istenantshare",super.isEnabletneant());
|
||||
if(super.isEnabletneant()) {
|
||||
//多租户启用 非超级管理员 一定要选择租户才能进入界面
|
||||
if(!user.isSuperuser() && !StringUtils.isBlank(user.getOrgid()) && super.isTenantconsole() && MainContext.SYSTEM_ORGI.equals(user.getOrgi())) {
|
||||
if(!user.isSuperuser() && StringUtils.isNotBlank(user.getOrgid()) && super.isTenantconsole() && MainContext.SYSTEM_ORGI.equals(user.getOrgi())) {
|
||||
view = request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index"));
|
||||
}
|
||||
if(StringUtils.isBlank(user.getOrgid())) {
|
||||
|
@ -16,23 +16,19 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.basic.Viewport;
|
||||
import com.chatopera.cc.exception.CSKefuException;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.TenantRepository;
|
||||
import com.chatopera.cc.app.handler.api.rest.QueryParams;
|
||||
import com.chatopera.cc.app.model.StreamingFile;
|
||||
import com.chatopera.cc.app.model.SystemConfig;
|
||||
import com.chatopera.cc.app.model.Tenant;
|
||||
import com.chatopera.cc.app.model.User;
|
||||
import com.chatopera.cc.app.persistence.blob.JpaBlobHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.StreamingFileRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TenantRepository;
|
||||
import com.chatopera.cc.exception.CSKefuException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
@ -45,9 +41,16 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.model.SystemConfig;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
||||
|
||||
|
||||
@Controller
|
||||
@ -58,6 +61,12 @@ public class Handler {
|
||||
@Autowired
|
||||
private TenantRepository tenantRes;
|
||||
|
||||
@Autowired
|
||||
private JpaBlobHelper jpaBlobHelper;
|
||||
|
||||
@Autowired
|
||||
private StreamingFileRepository streamingFileRes;
|
||||
|
||||
public final static int PAGE_SIZE_BG = 1;
|
||||
public final static int PAGE_SIZE_TW = 20;
|
||||
public final static int PAGE_SIZE_FV = 50;
|
||||
@ -72,11 +81,12 @@ public class Handler {
|
||||
if (StringUtils.isBlank(authorization) && request.getCookies() != null) {
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
if (cookie.getName().equals("authorization")) {
|
||||
authorization = cookie.getValue() ; break ;
|
||||
authorization = cookie.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!StringUtils.isBlank(authorization)){
|
||||
if (StringUtils.isNotBlank(authorization)) {
|
||||
user = (User) CacheHelper.getApiUserCacheBean().getCacheObject(authorization, MainContext.SYSTEM_ORGI);
|
||||
}
|
||||
if (user == null) {
|
||||
@ -94,6 +104,7 @@ public class Handler {
|
||||
|
||||
/**
|
||||
* 构建ElasticSearch基于部门查询的Filter
|
||||
*
|
||||
* @param request
|
||||
* @param boolQueryBuilder
|
||||
* @return
|
||||
@ -119,7 +130,6 @@ public class Handler {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param queryBuilder
|
||||
* @param request
|
||||
*/
|
||||
@ -127,56 +137,56 @@ public class Handler {
|
||||
queryBuilder.must(termQuery("orgi", this.getOrgi(request)));
|
||||
|
||||
//搜索框
|
||||
if(!StringUtils.isBlank(request.getParameter("q"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("q"))) {
|
||||
String q = request.getParameter("q");
|
||||
q = q.replaceAll("(OR|AND|NOT|:|\\(|\\))", "");
|
||||
if(!StringUtils.isBlank(q)){
|
||||
if (StringUtils.isNotBlank(q)) {
|
||||
queryBuilder.must(QueryBuilders.boolQuery().must(new QueryStringQueryBuilder(q).defaultOperator(Operator.AND)));
|
||||
map.put("q", q);
|
||||
}
|
||||
}
|
||||
|
||||
//筛选表单
|
||||
if(!StringUtils.isBlank(request.getParameter("filterid"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("filterid"))) {
|
||||
queryBuilder.must(termQuery("filterid", request.getParameter("filterid")));
|
||||
map.put("filterid", request.getParameter("filterid"));
|
||||
}
|
||||
|
||||
//批次
|
||||
if(!StringUtils.isBlank(request.getParameter("batid"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("batid"))) {
|
||||
queryBuilder.must(termQuery("batid", request.getParameter("batid")));
|
||||
map.put("batid", request.getParameter("batid"));
|
||||
}
|
||||
|
||||
//活动
|
||||
if(!StringUtils.isBlank(request.getParameter("actid"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("actid"))) {
|
||||
queryBuilder.must(termQuery("actid", request.getParameter("actid")));
|
||||
map.put("actid", request.getParameter("actid"));
|
||||
}
|
||||
|
||||
//业务状态
|
||||
if(!StringUtils.isBlank(request.getParameter("workstatus"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("workstatus"))) {
|
||||
queryBuilder.must(termQuery("workstatus", request.getParameter("workstatus")));
|
||||
map.put("workstatus", request.getParameter("workstatus"));
|
||||
}
|
||||
|
||||
//拨打状态
|
||||
if(!StringUtils.isBlank(request.getParameter("callstatus"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("callstatus"))) {
|
||||
queryBuilder.must(termQuery("callstatus", request.getParameter("callstatus")));
|
||||
map.put("callstatus", request.getParameter("callstatus"));
|
||||
}
|
||||
|
||||
//预约状态
|
||||
if(!StringUtils.isBlank(request.getParameter("apstatus"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("apstatus"))) {
|
||||
queryBuilder.must(termQuery("apstatus", request.getParameter("apstatus")));
|
||||
map.put("apstatus", request.getParameter("apstatus"));
|
||||
}
|
||||
|
||||
RangeQueryBuilder rangeQuery = null;
|
||||
//拨打时间区间查询
|
||||
if(!StringUtils.isBlank(request.getParameter("callbegin")) || !StringUtils.isBlank(request.getParameter("callend"))){
|
||||
if (StringUtils.isNotBlank(request.getParameter("callbegin")) || StringUtils.isNotBlank(request.getParameter("callend"))) {
|
||||
|
||||
if(!StringUtils.isBlank(request.getParameter("callbegin"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("callbegin"))) {
|
||||
try {
|
||||
|
||||
rangeQuery = QueryBuilders.rangeQuery("calltime").from(MainUtils.dateFormate.parse(request.getParameter("callbegin")).getTime());
|
||||
@ -185,7 +195,7 @@ public class Handler {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(!StringUtils.isBlank(request.getParameter("callend")) ) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("callend"))) {
|
||||
|
||||
try {
|
||||
|
||||
@ -204,9 +214,9 @@ public class Handler {
|
||||
map.put("callend", request.getParameter("callend"));
|
||||
}
|
||||
//预约时间区间查询
|
||||
if(!StringUtils.isBlank(request.getParameter("apbegin")) || !StringUtils.isBlank(request.getParameter("apend"))){
|
||||
if (StringUtils.isNotBlank(request.getParameter("apbegin")) || StringUtils.isNotBlank(request.getParameter("apend"))) {
|
||||
|
||||
if(!StringUtils.isBlank(request.getParameter("apbegin"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("apbegin"))) {
|
||||
try {
|
||||
|
||||
rangeQuery = QueryBuilders.rangeQuery("aptime").from(MainUtils.dateFormate.parse(request.getParameter("apbegin")).getTime());
|
||||
@ -215,7 +225,7 @@ public class Handler {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(!StringUtils.isBlank(request.getParameter("apend")) ) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("apend"))) {
|
||||
|
||||
try {
|
||||
|
||||
@ -230,7 +240,6 @@ public class Handler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
map.put("apbegin", request.getParameter("apbegin"));
|
||||
map.put("apend", request.getParameter("apend"));
|
||||
@ -241,22 +250,22 @@ public class Handler {
|
||||
}
|
||||
|
||||
//外呼任务id
|
||||
if(!StringUtils.isBlank(request.getParameter("taskid"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("taskid"))) {
|
||||
queryBuilder.must(termQuery("taskid", request.getParameter("taskid")));
|
||||
map.put("taskid", request.getParameter("taskid"));
|
||||
}
|
||||
//坐席
|
||||
if(!StringUtils.isBlank(request.getParameter("owneruser"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("owneruser"))) {
|
||||
queryBuilder.must(termQuery("owneruser", request.getParameter("owneruser")));
|
||||
map.put("owneruser", request.getParameter("owneruser"));
|
||||
}
|
||||
//部门
|
||||
if(!StringUtils.isBlank(request.getParameter("ownerdept"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("ownerdept"))) {
|
||||
queryBuilder.must(termQuery("ownerdept", request.getParameter("ownerdept")));
|
||||
map.put("ownerdept", request.getParameter("ownerdept"));
|
||||
}
|
||||
//分配状态
|
||||
if(!StringUtils.isBlank(request.getParameter("status"))) {
|
||||
if (StringUtils.isNotBlank(request.getParameter("status"))) {
|
||||
queryBuilder.must(termQuery("status", request.getParameter("status")));
|
||||
map.put("status", request.getParameter("status"));
|
||||
}
|
||||
@ -268,12 +277,12 @@ public class Handler {
|
||||
User user = (User) request.getSession(true).getAttribute(MainContext.IM_USER_SESSION_NAME);
|
||||
if (user == null) {
|
||||
user = new User();
|
||||
if(!StringUtils.isBlank(userid)){
|
||||
if (StringUtils.isNotBlank(userid)) {
|
||||
user.setId(userid);
|
||||
} else {
|
||||
user.setId(MainUtils.getContextID(request.getSession().getId()));
|
||||
}
|
||||
if(!StringUtils.isBlank(nickname)){
|
||||
if (StringUtils.isNotBlank(nickname)) {
|
||||
user.setUsername(nickname);
|
||||
} else {
|
||||
user.setUsername(MainContext.GUEST_USER + "_" + MainUtils.genIDByKey(user.getId()));
|
||||
@ -293,14 +302,17 @@ public class Handler {
|
||||
|
||||
/**
|
||||
* 创建系统监控的 模板页面
|
||||
*
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
public Viewport createAdminTempletResponse(String page) {
|
||||
return new Viewport("/admin/include/tpl", page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建系统监控的 模板页面
|
||||
*
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
@ -310,6 +322,7 @@ public class Handler {
|
||||
|
||||
/**
|
||||
* 创建系统监控的 模板页面
|
||||
*
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
@ -322,7 +335,6 @@ public class Handler {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
@ -333,7 +345,7 @@ public class Handler {
|
||||
public int getP(HttpServletRequest request) {
|
||||
int page = 0;
|
||||
String p = request.getParameter("p");
|
||||
if(!StringUtils.isBlank(p) && p.matches("[\\d]*")){
|
||||
if (StringUtils.isNotBlank(p) && p.matches("[\\d]*")) {
|
||||
page = Integer.parseInt(p);
|
||||
if (page > 0) {
|
||||
page = page - 1;
|
||||
@ -345,7 +357,7 @@ public class Handler {
|
||||
public int getPs(HttpServletRequest request) {
|
||||
int pagesize = PAGE_SIZE_TW;
|
||||
String ps = request.getParameter("ps");
|
||||
if(!StringUtils.isBlank(ps) && ps.matches("[\\d]*")){
|
||||
if (StringUtils.isNotBlank(ps) && ps.matches("[\\d]*")) {
|
||||
pagesize = Integer.parseInt(ps);
|
||||
}
|
||||
return pagesize;
|
||||
@ -353,7 +365,7 @@ public class Handler {
|
||||
|
||||
public int getP(QueryParams params) {
|
||||
int page = 0;
|
||||
if(params!=null && !StringUtils.isBlank(params.getP()) && params.getP().matches("[\\d]*")){
|
||||
if (params != null && StringUtils.isNotBlank(params.getP()) && params.getP().matches("[\\d]*")) {
|
||||
page = Integer.parseInt(params.getP());
|
||||
if (page > 0) {
|
||||
page = page - 1;
|
||||
@ -364,7 +376,7 @@ public class Handler {
|
||||
|
||||
public int getPs(QueryParams params) {
|
||||
int pagesize = PAGE_SIZE_TW;
|
||||
if(params != null && !StringUtils.isBlank(params.getPs()) && params.getPs().matches("[\\d]*")){
|
||||
if (params != null && StringUtils.isNotBlank(params.getPs()) && params.getPs().matches("[\\d]*")) {
|
||||
pagesize = Integer.parseInt(params.getPs());
|
||||
}
|
||||
return pagesize;
|
||||
@ -374,7 +386,7 @@ public class Handler {
|
||||
public int get50Ps(HttpServletRequest request) {
|
||||
int pagesize = PAGE_SIZE_FV;
|
||||
String ps = request.getParameter("ps");
|
||||
if(!StringUtils.isBlank(ps) && ps.matches("[\\d]*")){
|
||||
if (StringUtils.isNotBlank(ps) && ps.matches("[\\d]*")) {
|
||||
pagesize = Integer.parseInt(ps);
|
||||
}
|
||||
return pagesize;
|
||||
@ -383,8 +395,10 @@ public class Handler {
|
||||
public String getOrgi(HttpServletRequest request) {
|
||||
return getUser(request).getOrgi();
|
||||
}
|
||||
|
||||
/**
|
||||
* 机构id
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@ -396,8 +410,10 @@ public class Handler {
|
||||
public Tenant getTenant(HttpServletRequest request) {
|
||||
return tenantRes.findById(getOrgi(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据是否租户共享获取orgi
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@ -412,6 +428,7 @@ public class Handler {
|
||||
|
||||
/**
|
||||
* 判断是否租户共享
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isTenantshare() {
|
||||
@ -424,6 +441,7 @@ public class Handler {
|
||||
|
||||
/**
|
||||
* 判断是否多租户
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnabletneant() {
|
||||
@ -433,8 +451,10 @@ public class Handler {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否多租户
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isTenantconsole() {
|
||||
@ -452,4 +472,23 @@ public class Handler {
|
||||
public void setStarttime(long starttime) {
|
||||
this.starttime = starttime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Blob保存文件
|
||||
* @param multipart
|
||||
* @return id
|
||||
* @throws IOException
|
||||
*/
|
||||
public String saveImageFileWithMultipart(MultipartFile multipart) throws IOException {
|
||||
StreamingFile sf = new StreamingFile();
|
||||
final String fileid = MainUtils.getUUID();
|
||||
sf.setId(fileid);
|
||||
sf.setMime(multipart.getContentType());
|
||||
sf.setData(jpaBlobHelper.createBlob(multipart.getInputStream(), multipart.getSize()));
|
||||
sf.setName(multipart.getOriginalFilename());
|
||||
streamingFileRes.save(sf);
|
||||
return fileid;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ package com.chatopera.cc.app.handler;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.repository.OrganRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.RoleAuthRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRoleRepository;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -78,10 +78,18 @@ public class LoginController extends Handler {
|
||||
private void organs(final User user, final String organ) {
|
||||
if (organ == null)
|
||||
return;
|
||||
|
||||
if (user.inMyorgans(organ))
|
||||
return;
|
||||
|
||||
user.getMyorgans().add(organ);
|
||||
List<Organ> y = organRepository.findByOrgiAndParent(user.getOrgi(), organ);
|
||||
for (Organ x : y) {
|
||||
try {
|
||||
organs(user, x.getId());
|
||||
} catch (Exception e) {
|
||||
logger.error("organs", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,42 +16,36 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.admin.channel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.CousultInvite;
|
||||
import com.chatopera.cc.app.model.Organ;
|
||||
import com.chatopera.cc.app.model.OrgiSkillRel;
|
||||
import com.chatopera.cc.app.model.User;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.persistence.repository.ConsultInviteRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OrganRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OrgiSkillRelRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.SNSAccountRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ServiceAiRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRepository;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/webim")
|
||||
public class WebIMController extends Handler {
|
||||
private final static Logger logger = LoggerFactory.getLogger(WebIMController.class);
|
||||
|
||||
@Autowired
|
||||
private ConsultInviteRepository invite;
|
||||
@ -79,6 +73,8 @@ public class WebIMController extends Handler {
|
||||
public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String snsid) {
|
||||
|
||||
CousultInvite coultInvite = invite.findBySnsaccountidAndOrgi(snsid, super.getOrgi(request));
|
||||
logger.info("[index] snsaccount Id {}, AiFirst {}", coultInvite.getSnsaccountid(), coultInvite.isAifirst());
|
||||
|
||||
if (coultInvite != null) {
|
||||
map.addAttribute("inviteData", coultInvite);
|
||||
map.addAttribute("skillList", getOrgans(request));
|
||||
@ -88,13 +84,13 @@ public class WebIMController extends Handler {
|
||||
|
||||
map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request)));
|
||||
}
|
||||
return request(super.createAdminTempletResponse("/admin/app/index"));
|
||||
return request(super.createAdminTempletResponse("/admin/webim/index"));
|
||||
}
|
||||
|
||||
@RequestMapping("/save")
|
||||
@Menu(type = "admin", subtype = "app", admin = true)
|
||||
public ModelAndView save(HttpServletRequest request, @Valid CousultInvite inviteData, @RequestParam(value = "webimlogo", required = false) MultipartFile webimlogo, @RequestParam(value = "agentheadimg", required = false) MultipartFile agentheadimg) throws IOException {
|
||||
if(!StringUtils.isBlank(inviteData.getSnsaccountid())){
|
||||
if (StringUtils.isNotBlank(inviteData.getSnsaccountid())) {
|
||||
CousultInvite tempData = invite.findBySnsaccountidAndOrgi(inviteData.getSnsaccountid(), super.getOrgi(request));
|
||||
if (tempData != null) {
|
||||
tempData.setConsult_vsitorbtn_model(inviteData.getConsult_vsitorbtn_model());
|
||||
@ -103,35 +99,24 @@ public class WebIMController extends Handler {
|
||||
tempData.setConsult_vsitorbtn_content(inviteData.getConsult_vsitorbtn_content());
|
||||
tempData.setConsult_vsitorbtn_display(inviteData.getConsult_vsitorbtn_display());
|
||||
tempData.setConsult_dialog_color(inviteData.getConsult_dialog_color());
|
||||
|
||||
inviteData = tempData;
|
||||
}
|
||||
} else {
|
||||
inviteData.setSnsaccountid(super.getUser(request).getId());
|
||||
}
|
||||
inviteData.setOrgi(super.getOrgi(request));
|
||||
// 网页品牌标识
|
||||
if (webimlogo != null && webimlogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
File logoDir = new File(path , "logo");
|
||||
if(!logoDir.exists()){
|
||||
logoDir.mkdirs() ;
|
||||
}
|
||||
String fileName = "logo/"+inviteData.getId()+webimlogo.getOriginalFilename().substring(webimlogo.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileCopyUtils.copy(webimlogo.getBytes(), new File(path , fileName));
|
||||
inviteData.setConsult_dialog_logo(fileName);
|
||||
inviteData.setConsult_dialog_logo(super.saveImageFileWithMultipart(webimlogo));
|
||||
}
|
||||
|
||||
// 网页坐席头像
|
||||
if (agentheadimg != null && agentheadimg.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
File headimgDir = new File(path , "headimg");
|
||||
if(!headimgDir.exists()){
|
||||
headimgDir.mkdirs() ;
|
||||
}
|
||||
String fileName = "headimg/"+inviteData.getId()+agentheadimg.getOriginalFilename().substring(agentheadimg.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileCopyUtils.copy(agentheadimg.getBytes(), new File(path , fileName));
|
||||
inviteData.setConsult_dialog_headimg(fileName);
|
||||
inviteData.setConsult_dialog_headimg(super.saveImageFileWithMultipart(agentheadimg));
|
||||
}
|
||||
invite.save(inviteData);
|
||||
CacheHelper.getSystemCacheBean().put(inviteData.getSnsaccountid(), inviteData, inviteData.getOrgi());
|
||||
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/app/index.html?snsid="+inviteData.getSnsaccountid()));
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/webim/index.html?snsid=" + inviteData.getSnsaccountid()));
|
||||
}
|
||||
|
||||
@RequestMapping("/profile")
|
||||
@ -145,14 +130,14 @@ public class WebIMController extends Handler {
|
||||
map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request)));
|
||||
|
||||
map.put("serviceAiList", serviceAiRes.findByOrgi(super.getOrgi(request)));
|
||||
return request(super.createAdminTempletResponse("/admin/app/profile"));
|
||||
return request(super.createAdminTempletResponse("/admin/webim/profile"));
|
||||
}
|
||||
|
||||
@RequestMapping("/profile/save")
|
||||
@Menu(type = "admin", subtype = "profile", admin = true)
|
||||
public ModelAndView saveprofile(HttpServletRequest request, @Valid CousultInvite inviteData, @RequestParam(value = "dialogad", required = false) MultipartFile dialogad) throws IOException {
|
||||
CousultInvite tempInviteData;
|
||||
if(inviteData!=null && !StringUtils.isBlank(inviteData.getId())){
|
||||
if (inviteData != null && StringUtils.isNotBlank(inviteData.getId())) {
|
||||
tempInviteData = invite.findOne(inviteData.getId());
|
||||
if (tempInviteData != null) {
|
||||
tempInviteData.setDialog_name(inviteData.getDialog_name());
|
||||
@ -204,14 +189,8 @@ public class WebIMController extends Handler {
|
||||
|
||||
tempInviteData.setCtrlenter(inviteData.isCtrlenter());
|
||||
|
||||
if(dialogad!=null && !StringUtils.isBlank(dialogad.getName()) && dialogad.getBytes()!=null && dialogad.getBytes().length >0){
|
||||
String fileName = "ad/"+inviteData.getId()+dialogad.getOriginalFilename().substring(dialogad.getOriginalFilename().lastIndexOf(".")) ;
|
||||
File file = new File(path , fileName) ;
|
||||
if(!file.getParentFile().exists()){
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
FileCopyUtils.copy(dialogad.getBytes(), file);
|
||||
tempInviteData.setDialog_ad(fileName);
|
||||
if (dialogad != null && StringUtils.isNotBlank(dialogad.getName()) && dialogad.getBytes() != null && dialogad.getBytes().length > 0) {
|
||||
tempInviteData.setDialog_ad(super.saveImageFileWithMultipart(dialogad));
|
||||
}
|
||||
invite.save(tempInviteData);
|
||||
inviteData = tempInviteData;
|
||||
@ -220,7 +199,7 @@ public class WebIMController extends Handler {
|
||||
invite.save(inviteData);
|
||||
}
|
||||
CacheHelper.getSystemCacheBean().put(inviteData.getSnsaccountid(), inviteData, inviteData.getOrgi());
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/app/profile.html?snsid="+inviteData.getSnsaccountid()));
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/webim/profile.html?snsid=" + inviteData.getSnsaccountid()));
|
||||
}
|
||||
|
||||
@RequestMapping("/invote")
|
||||
@ -232,14 +211,14 @@ public class WebIMController extends Handler {
|
||||
}
|
||||
map.addAttribute("import", request.getServerPort());
|
||||
map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request)));
|
||||
return request(super.createAdminTempletResponse("/admin/app/invote"));
|
||||
return request(super.createAdminTempletResponse("/admin/webim/invote"));
|
||||
}
|
||||
|
||||
@RequestMapping("/invote/save")
|
||||
@Menu(type = "admin", subtype = "profile", admin = true)
|
||||
public ModelAndView saveinvote(HttpServletRequest request, @Valid CousultInvite inviteData, @RequestParam(value = "invotebg", required = false) MultipartFile invotebg) throws IOException {
|
||||
CousultInvite tempInviteData;
|
||||
if(inviteData!=null && !StringUtils.isBlank(inviteData.getId())){
|
||||
if (inviteData != null && StringUtils.isNotBlank(inviteData.getId())) {
|
||||
tempInviteData = invite.findOne(inviteData.getId());
|
||||
if (tempInviteData != null) {
|
||||
tempInviteData.setConsult_invite_enable(inviteData.isConsult_invite_enable());
|
||||
@ -250,14 +229,8 @@ public class WebIMController extends Handler {
|
||||
|
||||
tempInviteData.setConsult_invite_color(inviteData.getConsult_invite_color());
|
||||
|
||||
if(invotebg!=null && !StringUtils.isBlank(invotebg.getName()) && invotebg.getBytes()!=null && invotebg.getBytes().length >0){
|
||||
String fileName = "invote/"+inviteData.getId()+invotebg.getOriginalFilename().substring(invotebg.getOriginalFilename().lastIndexOf(".")) ;
|
||||
File file = new File(path , fileName) ;
|
||||
if(!file.getParentFile().exists()){
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
FileCopyUtils.copy(invotebg.getBytes(), file);
|
||||
tempInviteData.setConsult_invite_bg(fileName);
|
||||
if (invotebg != null && StringUtils.isNotBlank(invotebg.getName()) && invotebg.getBytes() != null && invotebg.getBytes().length > 0) {
|
||||
tempInviteData.setConsult_invite_bg(super.saveImageFileWithMultipart(invotebg));
|
||||
}
|
||||
invite.save(tempInviteData);
|
||||
inviteData = tempInviteData;
|
||||
@ -266,11 +239,12 @@ public class WebIMController extends Handler {
|
||||
invite.save(inviteData);
|
||||
}
|
||||
CacheHelper.getSystemCacheBean().put(inviteData.getSnsaccountid(), inviteData, inviteData.getOrgi());
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/app/invote.html?snsid="+inviteData.getSnsaccountid()));
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/webim/invote.html?snsid=" + inviteData.getSnsaccountid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前产品下组织信息
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@ -290,10 +264,11 @@ public class WebIMController extends Handler {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前产品下人员信息
|
||||
*
|
||||
* @param request
|
||||
* @param q
|
||||
* @return
|
||||
*/
|
||||
private List<User> getUsers(HttpServletRequest request) {
|
||||
|
@ -16,28 +16,20 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.admin.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.Secret;
|
||||
import com.chatopera.cc.app.model.SysDic;
|
||||
import com.chatopera.cc.app.model.SystemConfig;
|
||||
import com.chatopera.cc.app.model.UKeFuDic;
|
||||
import com.chatopera.cc.app.persistence.repository.SecretRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.SystemConfigRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.SystemMessageRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TemplateRepository;
|
||||
import com.chatopera.cc.app.model.Secret;
|
||||
import com.chatopera.cc.app.model.SysDic;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.corundumstudio.socketio.SocketIOServer;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -50,10 +42,16 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.corundumstudio.socketio.SocketIOServer;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.SystemConfig;
|
||||
import com.chatopera.cc.app.model.UKeFuDic;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/config")
|
||||
@ -122,10 +120,10 @@ public class SystemConfigController extends Handler{
|
||||
|
||||
map.addAttribute("sysMessageList", systemMessageRes.findByMsgtypeAndOrgi(MainContext.SystemMessageType.EMAIL.toString(), super.getOrgi(request)));
|
||||
|
||||
if(!StringUtils.isBlank(execute) && execute.equals("false")){
|
||||
if (StringUtils.isNotBlank(execute) && execute.equals("false")) {
|
||||
map.addAttribute("execute", execute);
|
||||
}
|
||||
if(!StringUtils.isBlank(request.getParameter("msg"))){
|
||||
if (StringUtils.isNotBlank(request.getParameter("msg"))) {
|
||||
map.addAttribute("msg", request.getParameter("msg"));
|
||||
}
|
||||
return request(super.createAdminTempletResponse("/admin/config/index"));
|
||||
@ -158,6 +156,7 @@ public class SystemConfigController extends Handler{
|
||||
|
||||
/**
|
||||
* 危险操作,请谨慎调用 , WebLogic/WebSphere/Oracle等中间件服务器禁止调用
|
||||
*
|
||||
* @param map
|
||||
* @param request
|
||||
* @return
|
||||
@ -216,30 +215,24 @@ public class SystemConfigController extends Handler{
|
||||
}
|
||||
}
|
||||
|
||||
if(loginlogo!=null && !StringUtils.isBlank(loginlogo.getOriginalFilename()) && loginlogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
String logoFileName = "logo/"+ MainUtils.md5(loginlogo.getOriginalFilename())+loginlogo.getOriginalFilename().substring(loginlogo.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileUtils.writeByteArrayToFile(new File(path ,logoFileName), loginlogo.getBytes());
|
||||
systemConfig.setLoginlogo(logoFileName);
|
||||
if (loginlogo != null && StringUtils.isNotBlank(loginlogo.getOriginalFilename()) && loginlogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
systemConfig.setLoginlogo(super.saveImageFileWithMultipart(loginlogo));
|
||||
}
|
||||
if(consolelogo!=null && !StringUtils.isBlank(consolelogo.getOriginalFilename()) && consolelogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
String consoleLogoFileName = "logo/"+ MainUtils.md5(consolelogo.getOriginalFilename())+consolelogo.getOriginalFilename().substring(consolelogo.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileUtils.writeByteArrayToFile(new File(path ,consoleLogoFileName), consolelogo.getBytes());
|
||||
systemConfig.setConsolelogo(consoleLogoFileName);
|
||||
if (consolelogo != null && StringUtils.isNotBlank(consolelogo.getOriginalFilename()) && consolelogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
systemConfig.setConsolelogo(super.saveImageFileWithMultipart(consolelogo));
|
||||
}
|
||||
if(favlogo!=null && !StringUtils.isBlank(favlogo.getOriginalFilename()) && consolelogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
String favLogoFileName = "logo/"+ MainUtils.md5(favlogo.getOriginalFilename())+favlogo.getOriginalFilename().substring(favlogo.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileUtils.writeByteArrayToFile(new File(path ,favLogoFileName), favlogo.getBytes());
|
||||
systemConfig.setFavlogo(favLogoFileName);
|
||||
if (favlogo != null && StringUtils.isNotBlank(favlogo.getOriginalFilename()) && consolelogo.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
systemConfig.setFavlogo(super.saveImageFileWithMultipart(favlogo));
|
||||
}
|
||||
|
||||
if(secret!=null && !StringUtils.isBlank(secret.getPassword())){
|
||||
if (secret != null && StringUtils.isNotBlank(secret.getPassword())) {
|
||||
List<Secret> secretConfig = secRes.findByOrgi(super.getOrgi(request));
|
||||
String repassword = request.getParameter("repassword");
|
||||
if(!StringUtils.isBlank(repassword) && repassword.equals(secret.getPassword())){
|
||||
if (StringUtils.isNotBlank(repassword) && repassword.equals(secret.getPassword())) {
|
||||
if (secretConfig != null && secretConfig.size() > 0) {
|
||||
Secret tempSecret = secretConfig.get(0);
|
||||
String oldpass = request.getParameter("oldpass");
|
||||
if(!StringUtils.isBlank(oldpass) && MainUtils.md5(oldpass).equals(tempSecret.getPassword())){
|
||||
if (StringUtils.isNotBlank(oldpass) && MainUtils.md5(oldpass).equals(tempSecret.getPassword())) {
|
||||
tempSecret.setPassword(MainUtils.md5(secret.getPassword()));
|
||||
msg = "1";
|
||||
tempSecret.setEnable(true);
|
||||
|
@ -16,20 +16,21 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.admin.users;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRoleRepository;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.AgentStatus;
|
||||
import com.chatopera.cc.app.model.User;
|
||||
import com.chatopera.cc.app.model.UserRole;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRoleRepository;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@ -38,24 +39,22 @@ import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRepository;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.User;
|
||||
import com.chatopera.cc.app.model.UserRole;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 程序猿DD
|
||||
* @version 1.0.0
|
||||
* @blog http://blog.didispace.com
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/admin/user")
|
||||
public class UsersController extends Handler {
|
||||
private final static Logger logger = LoggerFactory.getLogger(UsersController.class);
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
@ -135,8 +134,8 @@ public class UsersController extends Handler{
|
||||
msg = "mobile_exist";
|
||||
return msg;
|
||||
}
|
||||
List<User> tempUserList = userRepository.findBySipaccountAndDatastatus(user.getSipaccount(),false) ;
|
||||
if(tempUserList.size()!=0&&user.getSipaccount()!="") {
|
||||
|
||||
if (!validUserCallcenterParams(user)) {
|
||||
msg = "sip_account_exist";
|
||||
return msg;
|
||||
}
|
||||
@ -220,11 +219,12 @@ public class UsersController extends Handler{
|
||||
msg = "mobile_exist";
|
||||
return msg;
|
||||
}
|
||||
List<User> tempUserList = userRepository.findBySipaccountAndDatastatus(user.getSipaccount(),false) ;
|
||||
if(tempUserList.size()!=0&&user.getSipaccount()!=""&&!user.getSipaccount().equals(oldUser.getSipaccount())) {
|
||||
|
||||
if (!validUserCallcenterParams(user)) {
|
||||
msg = "sip_account_exist";
|
||||
return msg;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@ -245,4 +245,19 @@ public class UsersController extends Handler{
|
||||
return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg=" + msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据是否开启呼叫中心模块检测账号
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
private boolean validUserCallcenterParams(final User user) {
|
||||
if (user.isCallcenter() && MainContext.isEnableCalloutModule()) {
|
||||
List<User> tempUserList = userRepository.findBySipaccountAndDatastatus(user.getSipaccount(), false);
|
||||
if (tempUserList.size() != 0 && user.getSipaccount() != "") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -582,7 +582,7 @@ public class ApiChatbotController extends Handler {
|
||||
}
|
||||
} catch (ChatbotAPIRuntimeException e) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "智能问答引擎服务异常。" + e.toString());
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "智能问答引擎服务异常,该机器人【chatbotID】已经存在或服务不能访问到,请联系 [info@chatopera.com] 获得支持。");
|
||||
return resp;
|
||||
} catch (MalformedURLException e) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4);
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.chatopera.cc.app.handler.api.rest;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.exception.CSKefuRestException;
|
||||
@ -154,6 +155,7 @@ public class ApiContactNotesController extends Handler {
|
||||
}
|
||||
|
||||
ContactNotes cn = new ContactNotes();
|
||||
cn.setId(MainUtils.getUUID());
|
||||
cn.setCategory(payload.get("category").getAsString());
|
||||
cn.setContent(payload.get("content").getAsString());
|
||||
cn.setCreater(payload.get("creater").getAsString());
|
||||
|
@ -16,33 +16,25 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.apps.agent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.util.*;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.exception.CSKefuException;
|
||||
import com.chatopera.cc.exchange.DataExchangeInterface;
|
||||
import com.chatopera.cc.util.mobile.MobileAddress;
|
||||
import com.chatopera.cc.util.mobile.MobileNumberUtils;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.blob.JpaBlobHelper;
|
||||
import com.chatopera.cc.app.persistence.es.ContactsRepository;
|
||||
import com.chatopera.cc.app.persistence.es.QuickReplyRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import com.chatopera.cc.exception.CSKefuException;
|
||||
import com.chatopera.cc.exchange.DataExchangeInterface;
|
||||
import com.chatopera.cc.util.*;
|
||||
import com.chatopera.cc.util.mobile.MobileAddress;
|
||||
import com.chatopera.cc.util.mobile.MobileNumberUtils;
|
||||
import freemarker.template.TemplateException;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -62,10 +54,16 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
|
||||
import freemarker.template.TemplateException;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/agent")
|
||||
@ -149,6 +147,12 @@ public class AgentController extends Handler {
|
||||
@Autowired
|
||||
private ConsultInviteRepository inviteRepository;
|
||||
|
||||
@Autowired
|
||||
private StreamingFileRepository streamingFileRepository;
|
||||
|
||||
@Autowired
|
||||
private JpaBlobHelper jpaBlobHelper;
|
||||
|
||||
@Value("${web.upload-path}")
|
||||
private String path;
|
||||
|
||||
@ -163,12 +167,13 @@ public class AgentController extends Handler {
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("sort")) {
|
||||
sort = cookie.getValue() ;break ;
|
||||
sort = cookie.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!StringUtils.isBlank(sort)){
|
||||
if (StringUtils.isNotBlank(sort)) {
|
||||
List<Order> list = new ArrayList<Order>();
|
||||
if (sort.equals("lastmessage")) {
|
||||
list.add(new Order(Direction.DESC, "status"));
|
||||
@ -207,7 +212,7 @@ public class AgentController extends Handler {
|
||||
agentUser = (AgentUser) agentUserList.get(0);
|
||||
view.addObject("curagentuser", agentUser);
|
||||
view.addObject("inviteData", OnlineUserUtils.cousult(agentUser.getAppid(), agentUser.getOrgi(), inviteRepository));
|
||||
if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
List<AgentServiceSummary> summarizes = this.serviceSummaryRes.findByAgentserviceidAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request));
|
||||
if (summarizes.size() > 0) {
|
||||
view.addObject("summary", summarizes.get(0));
|
||||
@ -216,7 +221,7 @@ public class AgentController extends Handler {
|
||||
|
||||
view.addObject("agentUserMessageList", this.chatMessageRepository.findByUsessionAndOrgi(agentUser.getUserid(), super.getOrgi(request), new PageRequest(0, 20, Direction.DESC, "updatetime")));
|
||||
AgentService agentService = null;
|
||||
if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
agentService = this.agentServiceRepository.findOne(agentUser.getAgentserviceid());
|
||||
view.addObject("curAgentService", agentService);
|
||||
|
||||
@ -246,10 +251,10 @@ public class AgentController extends Handler {
|
||||
view.addObject("onlineUser", onlineUser);
|
||||
}
|
||||
} else if (MainContext.ChannelTypeEnum.PHONE.toString().equals(agentUser.getChannel())) {
|
||||
if(agentService!=null && !StringUtils.isBlank(agentService.getOwner())) {
|
||||
if (agentService != null && StringUtils.isNotBlank(agentService.getOwner())) {
|
||||
StatusEvent statusEvent = this.statusEventRes.findById(agentService.getOwner());
|
||||
if (statusEvent != null) {
|
||||
if(!StringUtils.isBlank(statusEvent.getHostid())) {
|
||||
if (StringUtils.isNotBlank(statusEvent.getHostid())) {
|
||||
PbxHost pbxHost = pbxHostRes.findById(statusEvent.getHostid());
|
||||
view.addObject("pbxHost", pbxHost);
|
||||
}
|
||||
@ -301,19 +306,19 @@ public class AgentController extends Handler {
|
||||
)
|
||||
);
|
||||
|
||||
if(!StringUtils.isBlank(agentService.getAppid())){
|
||||
if (StringUtils.isNotBlank(agentService.getAppid())) {
|
||||
map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(agentService.getAppid(), super.getOrgi(request)));
|
||||
}
|
||||
List<AgentUserContacts> relaList = agentUserContactsRes.findByUseridAndOrgi(agentService.getUserid(), agentService.getOrgi());
|
||||
if (relaList.size() > 0) {
|
||||
AgentUserContacts agentUserContacts = relaList.get(0);
|
||||
if(MainContext.model.get("contacts")!=null && !StringUtils.isBlank(agentUserContacts.getContactsid())){
|
||||
if (MainContext.model.get("contacts") != null && StringUtils.isNotBlank(agentUserContacts.getContactsid())) {
|
||||
DataExchangeInterface dataExchange = (DataExchangeInterface) MainContext.getContext().getBean("contacts");
|
||||
if (dataExchange != null) {
|
||||
map.addAttribute("contacts", dataExchange.getDataByIdAndOrgi(agentUserContacts.getContactsid(), super.getOrgi(request)));
|
||||
}
|
||||
}
|
||||
if(MainContext.model.get("workorders")!=null && !StringUtils.isBlank(agentUserContacts.getContactsid())){
|
||||
if (MainContext.model.get("workorders") != null && StringUtils.isNotBlank(agentUserContacts.getContactsid())) {
|
||||
DataExchangeInterface dataExchange = (DataExchangeInterface) MainContext.getContext().getBean("workorders");
|
||||
if (dataExchange != null) {
|
||||
map.addAttribute("workOrdersList", dataExchange.getListDataByIdAndOrgi(agentUserContacts.getContactsid(), super.getUser(request).getId(), super.getOrgi(request)));
|
||||
@ -325,7 +330,10 @@ public class AgentController extends Handler {
|
||||
|
||||
@RequestMapping("/agentuser")
|
||||
@Menu(type = "apps", subtype = "agent")
|
||||
public ModelAndView agentuser(ModelMap map , HttpServletRequest request , String id, String channel) throws IOException, TemplateException {
|
||||
public ModelAndView agentuser(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
String id,
|
||||
String channel) throws IOException, TemplateException {
|
||||
String mainagentuser = "/apps/agent/mainagentuser";
|
||||
if (channel.equals("phone")) {
|
||||
mainagentuser = "/apps/agent/mainagentuser_callout";
|
||||
@ -342,7 +350,7 @@ public class AgentController extends Handler {
|
||||
agentUserTaskRes.save(agentUserTask);
|
||||
}
|
||||
|
||||
if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
List<AgentServiceSummary> summarizes = this.serviceSummaryRes.findByAgentserviceidAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request));
|
||||
if (summarizes.size() > 0) {
|
||||
view.addObject("summary", summarizes.get(0));
|
||||
@ -351,7 +359,7 @@ public class AgentController extends Handler {
|
||||
|
||||
view.addObject("agentUserMessageList", this.chatMessageRepository.findByUsessionAndOrgi(agentUser.getUserid(), super.getOrgi(request), new PageRequest(0, 20, Direction.DESC, "updatetime")));
|
||||
AgentService agentService = null;
|
||||
if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
agentService = this.agentServiceRepository.findOne(agentUser.getAgentserviceid());
|
||||
view.addObject("curAgentService", agentService);
|
||||
if (agentService != null) {
|
||||
@ -381,10 +389,10 @@ public class AgentController extends Handler {
|
||||
view.addObject("onlineUser", onlineUser);
|
||||
}
|
||||
} else if (MainContext.ChannelTypeEnum.PHONE.toString().equals(agentUser.getChannel())) {
|
||||
if(agentService!=null && !StringUtils.isBlank(agentService.getOwner())) {
|
||||
if (agentService != null && StringUtils.isNotBlank(agentService.getOwner())) {
|
||||
StatusEvent statusEvent = this.statusEventRes.findById(agentService.getOwner());
|
||||
if (statusEvent != null) {
|
||||
if(!StringUtils.isBlank(statusEvent.getHostid())) {
|
||||
if (StringUtils.isNotBlank(statusEvent.getHostid())) {
|
||||
PbxHost pbxHost = pbxHostRes.findById(statusEvent.getHostid());
|
||||
view.addObject("pbxHost", pbxHost);
|
||||
}
|
||||
@ -448,11 +456,10 @@ public class AgentController extends Handler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/workorders/list")
|
||||
@Menu(type = "apps", subtype = "workorderslist")
|
||||
public ModelAndView workorderslist(HttpServletRequest request, String contactsid, ModelMap map) {
|
||||
if(MainContext.model.get("workorders")!=null && !StringUtils.isBlank(contactsid)){
|
||||
if (MainContext.model.get("workorders") != null && StringUtils.isNotBlank(contactsid)) {
|
||||
DataExchangeInterface dataExchange = (DataExchangeInterface) MainContext.getContext().getBean("workorders");
|
||||
if (dataExchange != null) {
|
||||
map.addAttribute("workOrdersList", dataExchange.getListDataByIdAndOrgi(contactsid, super.getUser(request).getId(), super.getOrgi(request)));
|
||||
@ -478,7 +485,7 @@ public class AgentController extends Handler {
|
||||
agentStatus.setAgentno(user.getId());
|
||||
agentStatus.setLogindate(new Date());
|
||||
|
||||
if(!StringUtils.isBlank(user.getOrgan())){
|
||||
if (StringUtils.isNotBlank(user.getOrgan())) {
|
||||
Organ organ = organRes.findByIdAndOrgi(user.getOrgan(), super.getOrgiByTenantshare(request));
|
||||
if (organ != null && organ.isSkill()) {
|
||||
agentStatus.setSkill(organ.getId());
|
||||
@ -586,7 +593,7 @@ public class AgentController extends Handler {
|
||||
AgentUser agentUser = agentUserRepository.findByIdAndOrgi(userid, super.getOrgi(request));
|
||||
if (agentUser != null && super.getUser(request).getId().equals(agentUser.getAgentno())) {
|
||||
AutomaticServiceDist.deleteAgentUser(agentUser, super.getOrgi(request));
|
||||
if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
AgentService agentService = agentServiceRepository.findByIdAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request));
|
||||
agentService.setStatus(MainContext.AgentUserStatusEnum.END.toString());
|
||||
agentServiceRepository.save(agentService);
|
||||
@ -652,7 +659,7 @@ public class AgentController extends Handler {
|
||||
blackListRes.save(tempBlackEntiry);
|
||||
blackEntity = tempBlackEntiry;
|
||||
}
|
||||
if(!StringUtils.isBlank(userid)){
|
||||
if (StringUtils.isNotBlank(userid)) {
|
||||
CacheHelper.getSystemCacheBean().put(userid, blackEntity, super.getOrgi(request));
|
||||
}
|
||||
}
|
||||
@ -678,58 +685,58 @@ public class AgentController extends Handler {
|
||||
|
||||
@RequestMapping("/image/upload")
|
||||
@Menu(type = "im", subtype = "image", access = false)
|
||||
public ModelAndView upload(ModelMap map,HttpServletRequest request , @RequestParam(value = "imgFile", required = false) MultipartFile imgFile , @Valid String id, @Valid String paste) throws IOException {
|
||||
public ModelAndView upload(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
@RequestParam(value = "imgFile", required = false) MultipartFile multipart,
|
||||
@Valid String id,
|
||||
@Valid String paste) throws IOException {
|
||||
ModelAndView view = request(super.createRequestPageTempletResponse("/apps/agent/upload"));
|
||||
UploadStatus upload = null ;
|
||||
String fileName = null ;
|
||||
if(imgFile!=null && imgFile.getOriginalFilename().lastIndexOf(".") > 0){
|
||||
UploadStatus notify = null;
|
||||
if (multipart != null && multipart.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
File uploadDir = new File(path, "upload");
|
||||
if (!uploadDir.exists()) {
|
||||
uploadDir.mkdirs();
|
||||
}
|
||||
String fileid = MainUtils.md5(imgFile.getBytes()) , fileURL = null , targetFile = null;
|
||||
String fileid = MainUtils.getUUID();
|
||||
String fileURL = null;
|
||||
ChatMessage data = new ChatMessage();
|
||||
if(imgFile.getContentType()!=null && imgFile.getContentType().indexOf("image") >= 0){
|
||||
fileName = "upload/"+fileid+"_original" ;
|
||||
File imageFile = new File(path , fileName) ;
|
||||
FileCopyUtils.copy(imgFile.getBytes(), imageFile);
|
||||
targetFile = "upload/"+fileid ;
|
||||
MainUtils.processImage(new File(path , targetFile), imageFile) ;
|
||||
StreamingFile sf = new StreamingFile();
|
||||
|
||||
|
||||
fileURL = "/res/image.html?id="+targetFile ;
|
||||
if(request.getServerPort() == 80){
|
||||
fileURL = "/res/image.html?id="+targetFile;
|
||||
if (multipart.getContentType() != null && multipart.getContentType().indexOf(Constants.ATTACHMENT_TYPE_IMAGE) >= 0) {
|
||||
// process thumbnail
|
||||
File original = new File(path, "upload/" + fileid + "_original");
|
||||
File thumbnail = new File(path, "upload/" + fileid);
|
||||
FileCopyUtils.copy(multipart.getBytes(), original);
|
||||
MainUtils.processImage(thumbnail, original);
|
||||
sf.setThumbnail(jpaBlobHelper.createBlobWithFile(thumbnail));
|
||||
fileURL = "/res/image.html?id=" + fileid;
|
||||
} else {
|
||||
fileURL = "/res/image.html?id="+targetFile;
|
||||
String attachid = processAttachmentFile(multipart, fileid, request);
|
||||
fileURL = "/res/file.html?id=" + attachid;
|
||||
}
|
||||
upload = new UploadStatus("0" , fileURL); //图片直接发送给 客户,不用返回
|
||||
|
||||
sf.setId(fileid);
|
||||
sf.setData(jpaBlobHelper.createBlob(multipart.getInputStream(), multipart.getSize()));
|
||||
sf.setName(multipart.getOriginalFilename());
|
||||
sf.setMime(multipart.getContentType());
|
||||
streamingFileRepository.save(sf);
|
||||
|
||||
data.setFilename(multipart.getOriginalFilename());
|
||||
data.setFilesize((int) multipart.getSize());
|
||||
data.setAttachmentid(fileid);
|
||||
}else{
|
||||
String attachid = processAttachmentFile(imgFile, request) ;
|
||||
|
||||
upload = new UploadStatus("0" , "/res/file.html?id="+attachid);
|
||||
fileURL = "/res/file.html?id="+attachid ;
|
||||
if(request.getServerPort() == 80){
|
||||
fileURL = "/res/file.html?id="+attachid;
|
||||
}else{
|
||||
fileURL = "/res/file.html?id="+attachid;
|
||||
}
|
||||
}
|
||||
data.setFilename(imgFile.getOriginalFilename());
|
||||
data.setFilesize((int) imgFile.getSize());
|
||||
notify = new UploadStatus("0", fileURL);
|
||||
|
||||
OutMessageRouter router = null ;
|
||||
AgentUser agentUser = agentUserRepository.findByIdAndOrgi(id, super.getOrgi(request));
|
||||
|
||||
if(agentUser!=null && paste == null){
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel()) ;
|
||||
if (agentUser != null && paste == null) { // 发送消息
|
||||
OutMessageRouter router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
if(router!=null){
|
||||
if (router != null) { // 发送消息给访客
|
||||
outMessage.setMessage(fileURL);
|
||||
outMessage.setFilename(imgFile.getOriginalFilename());
|
||||
outMessage.setFilesize((int) imgFile.getSize());
|
||||
if(imgFile.getContentType()!=null && imgFile.getContentType().indexOf("image") >= 0){
|
||||
outMessage.setFilename(multipart.getOriginalFilename());
|
||||
outMessage.setFilesize((int) multipart.getSize());
|
||||
if (multipart.getContentType() != null && multipart.getContentType().indexOf(Constants.ATTACHMENT_TYPE_IMAGE) >= 0) {
|
||||
outMessage.setMessageType(MainContext.MediaTypeEnum.IMAGE.toString());
|
||||
data.setMsgtype(MainContext.MediaTypeEnum.IMAGE.toString());
|
||||
} else {
|
||||
@ -738,7 +745,7 @@ public class AgentController extends Handler {
|
||||
}
|
||||
outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
outMessage.setCreatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
outMessage.setNickName(super.getUser(request).getUsername());
|
||||
outMessage.setNickName(super.getUser(request).getUname());
|
||||
|
||||
router.handler(agentUser.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage);
|
||||
}
|
||||
@ -750,7 +757,7 @@ public class AgentController extends Handler {
|
||||
data.setAgentserviceid(agentUser.getAgentserviceid());
|
||||
|
||||
data.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
if(!StringUtils.isBlank(agentUser.getAgentno())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentno())) {
|
||||
data.setTouser(agentUser.getUserid());
|
||||
}
|
||||
data.setChannel(agentUser.getChannel());
|
||||
@ -762,17 +769,16 @@ public class AgentController extends Handler {
|
||||
data.setOrgi(super.getUser(request).getOrgi());
|
||||
|
||||
data.setCreater(super.getUser(request).getId());
|
||||
data.setUsername(super.getUser(request).getUsername());
|
||||
data.setUsername(super.getUser(request).getUname());
|
||||
|
||||
chatMessageRepository.save(data);
|
||||
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
// 通知文件上传消息
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
}
|
||||
|
||||
} else {
|
||||
upload = new UploadStatus("请选择图片文件");
|
||||
notify = new UploadStatus("请选择图片文件");
|
||||
}
|
||||
map.addAttribute("upload", upload) ;
|
||||
map.addAttribute("upload", notify);
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -782,7 +788,7 @@ public class AgentController extends Handler {
|
||||
ChatMessage message = chatMessageRepository.findById(id);
|
||||
map.addAttribute("chatMessage", message);
|
||||
map.addAttribute("agentUser", CacheHelper.getAgentUserCacheBean().getCacheObject(message.getUserid(), message.getOrgi()));
|
||||
/*if(!StringUtils.isBlank(t)){
|
||||
/*if(StringUtils.isNotBlank(t)){
|
||||
map.addAttribute("t", t) ;
|
||||
}*/
|
||||
map.addAttribute("t", true);
|
||||
@ -791,23 +797,37 @@ public class AgentController extends Handler {
|
||||
|
||||
@RequestMapping("/message/image/upload")
|
||||
@Menu(type = "im", subtype = "image", access = false)
|
||||
public ModelAndView messageimage(ModelMap map,HttpServletRequest request , @RequestParam(value = "image", required = false) MultipartFile image , @Valid String id, @Valid String userid , @Valid String fileid) throws IOException {
|
||||
if(image!=null && !StringUtils.isBlank(fileid)){
|
||||
public ModelAndView messageimage(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
@RequestParam(value = "image", required = false) MultipartFile image,
|
||||
@Valid String id,
|
||||
@Valid String userid,
|
||||
@Valid String fileid) throws IOException {
|
||||
logger.info("messageimage id {}, fileid {}", id, fileid);
|
||||
if (image != null && StringUtils.isNotBlank(fileid)) {
|
||||
File tempFile = File.createTempFile(fileid, ".png");
|
||||
try {
|
||||
String fileName = "upload/"+fileid+"_cooperation" ;
|
||||
File imageFile = new File(path , fileName) ;
|
||||
// 创建临时图片文件
|
||||
if (!tempFile.getParentFile().exists()) {
|
||||
tempFile.getParentFile().mkdirs();
|
||||
}
|
||||
// 写入临时文件
|
||||
FileCopyUtils.copy(image.getBytes(), tempFile);
|
||||
ChatMessage chatMessage = chatMessageRepository.findById(id);
|
||||
chatMessage.setCooperation(true);
|
||||
chatMessageRepository.save(chatMessage);
|
||||
|
||||
// 写入协作文件
|
||||
String fileName = "upload/" + fileid + "_cooperation";
|
||||
File imageFile = new File(path, fileName);
|
||||
MainUtils.scaleImage(imageFile, tempFile, 0.1F);
|
||||
|
||||
|
||||
// 保存到数据库
|
||||
StreamingFile sf = streamingFileRepository.findOne(fileid);
|
||||
if (sf != null) {
|
||||
sf.setCooperation(jpaBlobHelper.createBlobWithFile(imageFile));
|
||||
streamingFileRepository.save(sf);
|
||||
}
|
||||
|
||||
OutMessageRouter router = null;
|
||||
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(chatMessage.getUserid(), chatMessage.getOrgi());
|
||||
@ -816,7 +836,7 @@ public class AgentController extends Handler {
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
if (router != null) {
|
||||
outMessage.setMessage("/res/image.html?id="+fileName);
|
||||
outMessage.setMessage("/res/image.html?id=" + fileid + "&cooperation=true");
|
||||
outMessage.setFilename(imageFile.getName());
|
||||
|
||||
outMessage.setAttachmentid(chatMessage.getAttachmentid());
|
||||
@ -825,7 +845,7 @@ public class AgentController extends Handler {
|
||||
outMessage.setMessageType(MainContext.MediaTypeEnum.ACTION.toString());
|
||||
outMessage.setCalltype(MainContext.CallTypeEnum.INVITE.toString());
|
||||
outMessage.setCreatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
outMessage.setNickName(super.getUser(request).getUsername());
|
||||
outMessage.setNickName(super.getUser(request).getUname());
|
||||
|
||||
router.handler(agentUser.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage);
|
||||
}
|
||||
@ -839,37 +859,34 @@ public class AgentController extends Handler {
|
||||
return request(super.createRequestPageTempletResponse("/public/success"));
|
||||
}
|
||||
|
||||
private String processAttachmentFile(MultipartFile file , HttpServletRequest request) throws IOException{
|
||||
private String processAttachmentFile(final MultipartFile multipart, final String fileid, HttpServletRequest request) throws IOException {
|
||||
String id = null;
|
||||
if(file.getSize() > 0){ //文件尺寸 限制 ?在 启动 配置中 设置 的最大值,其他地方不做限制
|
||||
String fileid = MainUtils.md5(file.getBytes()) ; //使用 文件的 MD5作为 ID,避免重复上传大文件
|
||||
if(!StringUtils.isBlank(fileid)){
|
||||
if (multipart.getSize() > 0) { //文件尺寸 限制 ?在 启动 配置中 设置 的最大值,其他地方不做限制
|
||||
AttachmentFile attachmentFile = new AttachmentFile();
|
||||
attachmentFile.setCreater(super.getUser(request).getId());
|
||||
attachmentFile.setOrgi(super.getOrgi(request));
|
||||
attachmentFile.setOrgan(super.getUser(request).getOrgan());
|
||||
attachmentFile.setModel(MainContext.ModelType.WEBIM.toString());
|
||||
attachmentFile.setFilelength((int) file.getSize());
|
||||
if(file.getContentType()!=null && file.getContentType().length() > 255){
|
||||
attachmentFile.setFiletype(file.getContentType().substring(0 , 255));
|
||||
attachmentFile.setFilelength((int) multipart.getSize());
|
||||
if (multipart.getContentType() != null && multipart.getContentType().length() > 255) {
|
||||
attachmentFile.setFiletype(multipart.getContentType().substring(0, 255));
|
||||
} else {
|
||||
attachmentFile.setFiletype(file.getContentType());
|
||||
attachmentFile.setFiletype(multipart.getContentType());
|
||||
}
|
||||
File uploadFile = new File(file.getOriginalFilename());
|
||||
File uploadFile = new File(multipart.getOriginalFilename());
|
||||
if (uploadFile.getName() != null && uploadFile.getName().length() > 255) {
|
||||
attachmentFile.setTitle(uploadFile.getName().substring(0, 255));
|
||||
} else {
|
||||
attachmentFile.setTitle(uploadFile.getName());
|
||||
}
|
||||
if(!StringUtils.isBlank(attachmentFile.getFiletype()) && attachmentFile.getFiletype().indexOf("image") >= 0){
|
||||
if (StringUtils.isNotBlank(attachmentFile.getFiletype()) && attachmentFile.getFiletype().indexOf(Constants.ATTACHMENT_TYPE_IMAGE) >= 0) {
|
||||
attachmentFile.setImage(true);
|
||||
}
|
||||
attachmentFile.setFileid(fileid);
|
||||
attachementRes.save(attachmentFile);
|
||||
FileUtils.writeByteArrayToFile(new File(path , "app/app/"+fileid), file.getBytes());
|
||||
FileUtils.writeByteArrayToFile(new File(path, "upload/" + fileid), multipart.getBytes());
|
||||
id = attachmentFile.getId();
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -877,7 +894,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping(value = "/contacts")
|
||||
@Menu(type = "apps", subtype = "contacts")
|
||||
public ModelAndView contacts(ModelMap map, HttpServletRequest request, @Valid String contactsid, @Valid String userid, @Valid String agentserviceid, @Valid String agentuserid) {
|
||||
if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(contactsid)){
|
||||
if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(contactsid)) {
|
||||
List<OnlineUser> onlineUserList = this.onlineUserRes.findByUseridAndOrgi(userid, super.getOrgi(request));
|
||||
if (onlineUserList.size() > 0) {
|
||||
OnlineUser onlineUser = onlineUserList.get(0);
|
||||
@ -917,19 +934,26 @@ public class AgentController extends Handler {
|
||||
|
||||
@RequestMapping(value = "/summary")
|
||||
@Menu(type = "apps", subtype = "summary")
|
||||
public ModelAndView summary(ModelMap map , HttpServletRequest request , @Valid String userid , @Valid String agentserviceid, @Valid String agentuserid){
|
||||
if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(agentuserid)){
|
||||
public ModelAndView summary(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
@Valid String userid,
|
||||
@Valid String agentserviceid,
|
||||
@Valid String agentuserid,
|
||||
@Valid String channel) {
|
||||
if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(agentuserid)) {
|
||||
AgentUser agentUser = this.agentUserRepository.findByIdAndOrgi(agentuserid, super.getOrgi(request));
|
||||
if(agentUser!=null && !StringUtils.isBlank(agentUser.getAgentserviceid())){
|
||||
if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
|
||||
List<AgentServiceSummary> summaries = this.serviceSummaryRes.findByAgentserviceidAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request));
|
||||
if (summaries.size() > 0) {
|
||||
map.addAttribute("summary", summaries.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
map.addAttribute("tags", tagRes.findByOrgiAndTagtype(super.getOrgi(request), MainContext.ModelType.SUMMARY.toString()));
|
||||
map.addAttribute("userid", userid);
|
||||
map.addAttribute("agentserviceid", agentserviceid);
|
||||
map.addAttribute("agentuserid", agentuserid);
|
||||
map.addAttribute("channel", channel);
|
||||
|
||||
}
|
||||
|
||||
@ -938,8 +962,15 @@ public class AgentController extends Handler {
|
||||
|
||||
@RequestMapping(value = "/summary/save")
|
||||
@Menu(type = "apps", subtype = "summarysave")
|
||||
public ModelAndView summarysave(ModelMap map , HttpServletRequest request , @Valid AgentServiceSummary summary , @Valid String contactsid , @Valid String userid , @Valid String agentserviceid, @Valid String agentuserid){
|
||||
if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(agentuserid)){
|
||||
public ModelAndView summarysave(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
@Valid AgentServiceSummary summary,
|
||||
@Valid String contactsid,
|
||||
@Valid String userid,
|
||||
@Valid String agentserviceid,
|
||||
@Valid String agentuserid,
|
||||
@Valid String channel) {
|
||||
if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(agentuserid)) {
|
||||
summary.setOrgi(super.getOrgi(request));
|
||||
summary.setCreater(super.getUser(request).getId());
|
||||
|
||||
@ -951,6 +982,7 @@ public class AgentController extends Handler {
|
||||
summary.setUsername(service.getUsername());
|
||||
summary.setAgentusername(service.getAgentusername());
|
||||
summary.setChannel(service.getChannel());
|
||||
summary.setContactsid(contactsid);
|
||||
summary.setLogindate(service.getLogindate());
|
||||
summary.setContactsid(service.getContactsid());
|
||||
summary.setEmail(service.getEmail());
|
||||
@ -958,13 +990,13 @@ public class AgentController extends Handler {
|
||||
serviceSummaryRes.save(summary);
|
||||
}
|
||||
|
||||
return request(super.createRequestPageTempletResponse("redirect:/agent/agentuser.html?id="+agentuserid)) ;
|
||||
return request(super.createRequestPageTempletResponse("redirect:/agent/agentuser.html?id=" + agentuserid + "&channel=" + channel));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/transfer")
|
||||
@Menu(type = "apps", subtype = "transfer")
|
||||
public ModelAndView transfer(ModelMap map, HttpServletRequest request, @Valid String userid, @Valid String agentserviceid, @Valid String agentuserid) {
|
||||
if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(agentuserid)){
|
||||
if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(agentuserid)) {
|
||||
//map.addAttribute("organList", organRes.findByOrgiAndOrgid(super.getOrgi(request),super.getOrgid(request))) ;
|
||||
|
||||
List<Organ> skillList = OnlineUserUtils.organ(super.getOrgi(request), true);
|
||||
@ -1005,7 +1037,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping(value = "/transfer/agent")
|
||||
@Menu(type = "apps", subtype = "transferagent")
|
||||
public ModelAndView transferagent(ModelMap map, HttpServletRequest request, @Valid String organ) {
|
||||
if(!StringUtils.isBlank(organ)){
|
||||
if (StringUtils.isNotBlank(organ)) {
|
||||
List<String> usersids = new ArrayList<String>();
|
||||
List<AgentStatus> agentStatusList = AutomaticServiceDist.getAgentStatus(organ, super.getOrgi(request));
|
||||
if (!agentStatusList.isEmpty()) {
|
||||
@ -1030,7 +1062,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping(value = "/transfer/save")
|
||||
@Menu(type = "apps", subtype = "transfersave")
|
||||
public ModelAndView transfersave(ModelMap map, HttpServletRequest request, @Valid String userid, @Valid String agentserviceid, @Valid String agentuserid, @Valid String agentno, @Valid String memo) {
|
||||
if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(agentuserid) && !StringUtils.isBlank(agentno)){
|
||||
if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(agentuserid) && StringUtils.isNotBlank(agentno)) {
|
||||
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(userid, super.getOrgi(request));
|
||||
AgentService agentService = this.agentServiceRepository.findByIdAndOrgi(agentserviceid, super.getOrgi(request));
|
||||
if (agentUser != null) {
|
||||
@ -1051,7 +1083,8 @@ public class AgentController extends Handler {
|
||||
agentService.setAgentno(agentno);
|
||||
agentService.setAgentusername(transAgentStatus.getUsername());
|
||||
}
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
// 通知转接消息
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
}
|
||||
} else {
|
||||
agentUser = agentUserRepository.findByIdAndOrgi(agentuserid, super.getOrgi(request));
|
||||
@ -1063,7 +1096,7 @@ public class AgentController extends Handler {
|
||||
|
||||
if (agentService != null) {
|
||||
agentService.setAgentno(agentno);
|
||||
if(!StringUtils.isBlank(memo)){
|
||||
if (StringUtils.isNotBlank(memo)) {
|
||||
agentService.setTransmemo(memo);
|
||||
}
|
||||
agentService.setTrans(true);
|
||||
@ -1076,8 +1109,6 @@ public class AgentController extends Handler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/quicklist")
|
||||
@Menu(type = "setting", subtype = "quickreply", admin = true)
|
||||
public ModelAndView quicklist(ModelMap map, HttpServletRequest request, @Valid String typeid) {
|
||||
@ -1087,7 +1118,7 @@ public class AgentController extends Handler {
|
||||
quickTypeList.addAll(priQuickTypeList);
|
||||
map.addAttribute("pubQuickTypeList", quickTypeList);
|
||||
|
||||
if(!StringUtils.isBlank(typeid)){
|
||||
if (StringUtils.isNotBlank(typeid)) {
|
||||
map.addAttribute("quickType", quickTypeRes.findByIdAndOrgi(typeid, super.getOrgi(request)));
|
||||
}
|
||||
|
||||
@ -1098,7 +1129,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping("/quickreply/add")
|
||||
@Menu(type = "setting", subtype = "quickreplyadd", admin = true)
|
||||
public ModelAndView quickreplyadd(ModelMap map, HttpServletRequest request, @Valid String parentid) {
|
||||
if(!StringUtils.isBlank(parentid)){
|
||||
if (StringUtils.isNotBlank(parentid)) {
|
||||
map.addAttribute("quickType", quickTypeRes.findByIdAndOrgi(parentid, super.getOrgi(request)));
|
||||
}
|
||||
map.addAttribute("quickTypeList", quickTypeRes.findByOrgiAndQuicktypeAndCreater(super.getOrgi(request), MainContext.QuickTypeEnum.PRI.toString(), super.getUser(request).getId()));
|
||||
@ -1108,7 +1139,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping("/quickreply/save")
|
||||
@Menu(type = "setting", subtype = "quickreply", admin = true)
|
||||
public ModelAndView quickreplysave(ModelMap map, HttpServletRequest request, @Valid QuickReply quickReply) {
|
||||
if(!StringUtils.isBlank(quickReply.getTitle()) && !StringUtils.isBlank(quickReply.getContent())){
|
||||
if (StringUtils.isNotBlank(quickReply.getTitle()) && StringUtils.isNotBlank(quickReply.getContent())) {
|
||||
quickReply.setOrgi(super.getOrgi(request));
|
||||
quickReply.setCreater(super.getUser(request).getId());
|
||||
quickReply.setType(MainContext.QuickTypeEnum.PRI.toString());
|
||||
@ -1126,6 +1157,7 @@ public class AgentController extends Handler {
|
||||
}
|
||||
return request(super.createRequestPageTempletResponse("redirect:/agent/quicklist.html?typeid=" + quickReply.getCate()));
|
||||
}
|
||||
|
||||
@RequestMapping("/quickreply/edit")
|
||||
@Menu(type = "setting", subtype = "quickreply", admin = true)
|
||||
public ModelAndView quickreplyedit(ModelMap map, HttpServletRequest request, @Valid String id) {
|
||||
@ -1141,7 +1173,7 @@ public class AgentController extends Handler {
|
||||
@RequestMapping("/quickreply/update")
|
||||
@Menu(type = "setting", subtype = "quickreply", admin = true)
|
||||
public ModelAndView quickreplyupdate(ModelMap map, HttpServletRequest request, @Valid QuickReply quickReply) {
|
||||
if(!StringUtils.isBlank(quickReply.getId())){
|
||||
if (StringUtils.isNotBlank(quickReply.getId())) {
|
||||
QuickReply temp = quickReplyRes.findOne(quickReply.getId());
|
||||
quickReply.setOrgi(super.getOrgi(request));
|
||||
quickReply.setCreater(super.getUser(request).getId());
|
||||
@ -1158,7 +1190,7 @@ public class AgentController extends Handler {
|
||||
@Menu(type = "apps", subtype = "kbs")
|
||||
public ModelAndView addtype(ModelMap map, HttpServletRequest request, @Valid String typeid) {
|
||||
map.addAttribute("quickTypeList", quickTypeRes.findByOrgiAndQuicktypeAndCreater(super.getOrgi(request), MainContext.QuickTypeEnum.PRI.toString(), super.getUser(request).getId()));
|
||||
if(!StringUtils.isBlank(typeid)){
|
||||
if (StringUtils.isNotBlank(typeid)) {
|
||||
map.addAttribute("quickType", quickTypeRes.findByIdAndOrgi(typeid, super.getOrgi(request)));
|
||||
}
|
||||
return request(super.createRequestPageTempletResponse("/apps/agent/quickreply/addtype"));
|
||||
@ -1213,6 +1245,7 @@ public class AgentController extends Handler {
|
||||
}
|
||||
return request(super.createRequestPageTempletResponse("redirect:/agent/quicklist.html" + (tempQuickType != null ? "?typeid=" + tempQuickType.getParentid() : "")));
|
||||
}
|
||||
|
||||
@RequestMapping({"/quickreply/content"})
|
||||
@Menu(type = "apps", subtype = "quickreply")
|
||||
public ModelAndView quickreplycontent(ModelMap map, HttpServletRequest request, @Valid String id) {
|
||||
|
@ -292,7 +292,7 @@ public class ContactsController extends Handler {
|
||||
values.add(MainUtils.transBean2Map(contacts));
|
||||
}
|
||||
|
||||
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
response.setHeader("content-disposition", "attachment;filename=CSKefu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
|
||||
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
|
||||
excelProcess.process();
|
||||
@ -317,7 +317,7 @@ public class ContactsController extends Handler {
|
||||
values.add(MainUtils.transBean2Map(contacts));
|
||||
}
|
||||
|
||||
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
response.setHeader("content-disposition", "attachment;filename=CSKefu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
|
||||
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
|
||||
excelProcess.process();
|
||||
@ -343,7 +343,7 @@ public class ContactsController extends Handler {
|
||||
values.add(MainUtils.transBean2Map(contacts));
|
||||
}
|
||||
|
||||
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
response.setHeader("content-disposition", "attachment;filename=CSKefu-Contacts-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
|
||||
|
||||
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
|
||||
excelProcess.process();
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
package com.chatopera.cc.app.handler.apps.internet;
|
||||
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.im.util.RichMediaUtils;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.persistence.blob.JpaBlobHelper;
|
||||
import com.chatopera.cc.app.persistence.es.ContactsRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.*;
|
||||
@ -78,6 +79,12 @@ public class IMController extends Handler {
|
||||
@Value("${web.upload-path}")
|
||||
private String path;
|
||||
|
||||
@Autowired
|
||||
private StreamingFileRepository streamingFileRepository;
|
||||
|
||||
@Autowired
|
||||
private JpaBlobHelper jpaBlobHelper;
|
||||
|
||||
@Autowired
|
||||
private ConsultInviteRepository inviteRepository;
|
||||
|
||||
@ -707,51 +714,79 @@ public class IMController extends Handler {
|
||||
|
||||
@RequestMapping("/image/upload")
|
||||
@Menu(type = "im", subtype = "image", access = true)
|
||||
public ModelAndView upload(ModelMap map, HttpServletRequest request, @RequestParam(value = "imgFile", required = false) MultipartFile imgFile, @Valid String channel, @Valid String userid, @Valid String username, @Valid String appid, @Valid String orgi, @Valid String paste) throws IOException {
|
||||
public ModelAndView upload(ModelMap map, HttpServletRequest request,
|
||||
@RequestParam(value = "imgFile", required = false) MultipartFile multipart,
|
||||
@Valid String channel,
|
||||
@Valid String userid,
|
||||
@Valid String username,
|
||||
@Valid String appid,
|
||||
@Valid String orgi,
|
||||
@Valid String paste) throws IOException {
|
||||
ModelAndView view = request(super.createRequestPageTempletResponse("/apps/im/upload"));
|
||||
UploadStatus upload = null;
|
||||
String fileName = null;
|
||||
if (imgFile != null && imgFile.getOriginalFilename().lastIndexOf(".") > 0 && StringUtils.isNotBlank(userid)) {
|
||||
if (multipart != null
|
||||
&& multipart.getOriginalFilename().lastIndexOf(".") > 0
|
||||
&& StringUtils.isNotBlank(userid)) {
|
||||
File uploadDir = new File(path, "upload");
|
||||
if (!uploadDir.exists()) {
|
||||
uploadDir.mkdirs();
|
||||
}
|
||||
String fileid = MainUtils.md5(imgFile.getBytes());
|
||||
if (imgFile.getContentType() != null && imgFile.getContentType().indexOf("image") >= 0) {
|
||||
|
||||
String fileid = MainUtils.getUUID();
|
||||
StreamingFile sf = new StreamingFile();
|
||||
sf.setId(fileid);
|
||||
sf.setName(multipart.getOriginalFilename());
|
||||
sf.setMime(multipart.getContentType());
|
||||
if (multipart.getContentType() != null
|
||||
&& multipart.getContentType().indexOf(Constants.ATTACHMENT_TYPE_IMAGE) >= 0) {
|
||||
// 检查文件格式
|
||||
String invalid = StreamingFileUtils.getInstance().validate(Constants.ATTACHMENT_TYPE_IMAGE, multipart.getOriginalFilename());
|
||||
if (invalid == null) {
|
||||
fileName = "upload/" + fileid + "_original";
|
||||
File imageFile = new File(path, fileName);
|
||||
FileCopyUtils.copy(imgFile.getBytes(), imageFile);
|
||||
FileCopyUtils.copy(multipart.getBytes(), imageFile);
|
||||
String thumbnailsFileName = "upload/" + fileid;
|
||||
MainUtils.processImage(new File(path, thumbnailsFileName), imageFile);
|
||||
File thumbnail = new File(path, thumbnailsFileName);
|
||||
MainUtils.processImage(thumbnail, imageFile);
|
||||
|
||||
// 存储数据库
|
||||
sf.setData(jpaBlobHelper.createBlob(multipart.getInputStream(), multipart.getSize()));
|
||||
sf.setThumbnail(jpaBlobHelper.createBlobWithFile(thumbnail));
|
||||
streamingFileRepository.save(sf);
|
||||
String fileUrl = "/res/image.html?id=" + fileid;
|
||||
upload = new UploadStatus("0", fileUrl);
|
||||
|
||||
upload = new UploadStatus("0", "/res/image.html?id=" + thumbnailsFileName);
|
||||
String image = "/res/image.html?id=" + thumbnailsFileName;
|
||||
if (request.getServerPort() == 80) {
|
||||
image = "/res/image.html?id=" + thumbnailsFileName;
|
||||
} else {
|
||||
image = "/res/image.html?id=" + thumbnailsFileName;
|
||||
}
|
||||
if (paste == null) {
|
||||
if (StringUtils.isNotBlank(channel)) {
|
||||
RichMediaUtils.uploadImageWithChannel(image, fileid, (int) imgFile.getSize(), imgFile.getName(), channel, userid, username, appid, orgi);
|
||||
RichMediaUtils.uploadImageWithChannel(fileUrl, fileid, (int) multipart.getSize(), multipart.getName(), channel, userid, username, appid, orgi);
|
||||
} else {
|
||||
RichMediaUtils.uploadImage(image, fileid, (int) imgFile.getSize(), imgFile.getName(), userid);
|
||||
RichMediaUtils.uploadImage(fileUrl, fileid, (int) multipart.getSize(), multipart.getName(), userid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String id = processAttachmentFile(imgFile, request);
|
||||
upload = new UploadStatus(invalid);
|
||||
}
|
||||
} else {
|
||||
String invalid = StreamingFileUtils.getInstance().validate(Constants.ATTACHMENT_TYPE_FILE, multipart.getOriginalFilename());
|
||||
if (invalid == null) {
|
||||
// 存储数据库
|
||||
sf.setData(jpaBlobHelper.createBlob(multipart.getInputStream(), multipart.getSize()));
|
||||
streamingFileRepository.save(sf);
|
||||
|
||||
// 存储到本地硬盘
|
||||
String id = processAttachmentFile(multipart, fileid, request);
|
||||
upload = new UploadStatus("0", "/res/file.html?id=" + id);
|
||||
String file = "/res/file.html?id=" + id;
|
||||
if (request.getServerPort() == 80) {
|
||||
file = "/res/file.html?id=" + id;
|
||||
} else {
|
||||
file = "/res/file.html?id=" + id;
|
||||
}
|
||||
File tempFile = new File(imgFile.getOriginalFilename());
|
||||
|
||||
File tempFile = new File(multipart.getOriginalFilename());
|
||||
if (StringUtils.isNotBlank(channel)) {
|
||||
RichMediaUtils.uploadFileWithChannel(file, (int) imgFile.getSize(), tempFile.getName(), channel, userid, username, appid, orgi, id);
|
||||
RichMediaUtils.uploadFileWithChannel(file, (int) multipart.getSize(), tempFile.getName(), channel, userid, username, appid, orgi, id);
|
||||
} else {
|
||||
RichMediaUtils.uploadFile(file, (int) imgFile.getSize(), tempFile.getName(), userid, id);
|
||||
RichMediaUtils.uploadFile(file, (int) multipart.getSize(), tempFile.getName(), userid, id);
|
||||
}
|
||||
} else {
|
||||
upload = new UploadStatus(invalid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -761,11 +796,9 @@ public class IMController extends Handler {
|
||||
return view;
|
||||
}
|
||||
|
||||
private String processAttachmentFile(MultipartFile file, HttpServletRequest request) throws IOException {
|
||||
private String processAttachmentFile(final MultipartFile file, final String fileid, HttpServletRequest request) throws IOException {
|
||||
String id = null;
|
||||
if (file.getSize() > 0) { //文件尺寸 限制 ?在 启动 配置中 设置 的最大值,其他地方不做限制
|
||||
String fileid = MainUtils.md5(file.getBytes()); //使用 文件的 MD5作为 ID,避免重复上传大文件
|
||||
if (StringUtils.isNotBlank(fileid)) {
|
||||
AttachmentFile attachmentFile = new AttachmentFile();
|
||||
attachmentFile.setCreater(super.getUser(request).getId());
|
||||
attachmentFile.setOrgi(super.getOrgi(request));
|
||||
@ -788,10 +821,9 @@ public class IMController extends Handler {
|
||||
}
|
||||
attachmentFile.setFileid(fileid);
|
||||
attachementRes.save(attachmentFile);
|
||||
FileUtils.writeByteArrayToFile(new File(path, "app/app/" + fileid), file.getBytes());
|
||||
FileUtils.writeByteArrayToFile(new File(path, "upload/" + fileid), file.getBytes());
|
||||
id = attachmentFile.getId();
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
}
|
@ -419,7 +419,7 @@ public class TopicController extends Handler{
|
||||
values.add(MainUtils.transBean2Map(topic)) ;
|
||||
}
|
||||
|
||||
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Contacts-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
|
||||
response.setHeader("content-disposition", "attachment;filename=CSKefu-Contacts-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
|
||||
if(table!=null){
|
||||
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
|
||||
excelProcess.process();
|
||||
|
@ -16,27 +16,17 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.apps.service;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.util.IP;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.IP;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@ -48,21 +38,16 @@ import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.persistence.repository.AgentServiceRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentStatusRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.LeaveMsgRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OrganRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OrgiSkillRelRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserRepository;
|
||||
import com.chatopera.cc.app.model.AgentService;
|
||||
import com.chatopera.cc.app.model.AgentStatus;
|
||||
import com.chatopera.cc.app.model.AgentUser;
|
||||
import com.chatopera.cc.app.model.AiUser;
|
||||
import com.chatopera.cc.app.model.LeaveMsg;
|
||||
import com.chatopera.cc.app.model.Organ;
|
||||
import com.chatopera.cc.app.model.OrgiSkillRel;
|
||||
import com.chatopera.cc.app.model.User;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/service")
|
||||
@ -212,7 +197,8 @@ public class ChatServiceController extends Handler {
|
||||
agentService.setAgentno(agentno);
|
||||
agentService.setAgentusername(transAgentStatus.getUsername());
|
||||
}
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
// TODO #111 通知转接消息
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
|
||||
}
|
||||
} else {
|
||||
agentUser = agentUserRepository.findByIdAndOrgi(agentService.getAgentuserid(), super.getOrgi(request));
|
||||
@ -374,14 +360,17 @@ public class ChatServiceController extends Handler {
|
||||
if (agentStatus != null) {
|
||||
agentStatusRepository.delete(agentStatus);
|
||||
}
|
||||
CacheHelper.getAgentStatusCacheBean().delete(agentStatus.getAgentno(), super.getOrgi(request));;
|
||||
CacheHelper.getAgentStatusCacheBean().delete(agentStatus.getAgentno(), super.getOrgi(request));
|
||||
;
|
||||
AutomaticServiceDist.publishMessage(super.getOrgi(request), "agent", "offline", super.getUser(request).getId());
|
||||
|
||||
|
||||
return request(super.createRequestPageTempletResponse("redirect:/service/agent/index.html"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 非管理员坐席
|
||||
*
|
||||
* @param map
|
||||
* @param request
|
||||
* @return
|
||||
@ -410,8 +399,10 @@ public class ChatServiceController extends Handler {
|
||||
map.put("userList", userList);
|
||||
return request(super.createAppsTempletResponse("/apps/service/user/index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员坐席
|
||||
*
|
||||
* @param map
|
||||
* @param request
|
||||
* @return
|
||||
@ -428,6 +419,7 @@ public class ChatServiceController extends Handler {
|
||||
map.put("userList", userList);
|
||||
return request(super.createAppsTempletResponse("/apps/service/adminagent/index"));
|
||||
}
|
||||
|
||||
@RequestMapping("/leavemsg/index")
|
||||
@Menu(type = "service", subtype = "leavemsg", admin = true)
|
||||
public ModelAndView leavemsg(ModelMap map, HttpServletRequest request) {
|
||||
|
@ -16,20 +16,14 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.apps.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.es.ContactsRepository;
|
||||
import com.chatopera.cc.app.persistence.impl.AgentUserService;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.AgentServiceSummary;
|
||||
import com.chatopera.cc.app.model.AgentUser;
|
||||
import com.chatopera.cc.app.model.AgentUserContacts;
|
||||
import com.chatopera.cc.app.model.OnlineUser;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@ -39,19 +33,9 @@ import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentServiceRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserContactsRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ChatMessageRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OnlineUserHisRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OnlineUserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ServiceSummaryRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TagRelationRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TagRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.UserEventRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.WeiXinUserRepository;
|
||||
import com.chatopera.cc.app.model.AgentService;
|
||||
import com.chatopera.cc.app.model.WeiXinUser;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/service")
|
||||
@ -96,13 +80,13 @@ public class OnlineUserController extends Handler {
|
||||
@RequestMapping("/online/index")
|
||||
@Menu(type = "service", subtype = "online", admin = true)
|
||||
public ModelAndView index(ModelMap map, HttpServletRequest request, String userid, String agentservice, @Valid String channel) {
|
||||
if(!StringUtils.isBlank(userid)){
|
||||
if (StringUtils.isNotBlank(userid)) {
|
||||
map.put("inviteResult", MainUtils.getWebIMInviteResult(onlineUserRes.findByOrgiAndUserid(super.getOrgi(request), userid)));
|
||||
map.put("tagRelationList", tagRelationRes.findByUserid(userid));
|
||||
map.put("onlineUserHistList", onlineUserHisRes.findByUseridAndOrgi(userid, super.getOrgi(request)));
|
||||
map.put("agentServicesAvg", onlineUserRes.countByUserForAvagTime(super.getOrgi(request), MainContext.AgentUserStatusEnum.END.toString(), userid));
|
||||
|
||||
List<AgentService> agentServiceList = agentServiceRes.findByUseridAndOrgi(userid, super.getOrgi(request)) ;
|
||||
List<AgentService> agentServiceList = agentServiceRes.findByUseridAndOrgiOrderByLogindateDesc(userid, super.getOrgi(request));
|
||||
|
||||
map.put("agentServiceList", agentServiceList);
|
||||
if (agentServiceList.size() > 0) {
|
||||
@ -112,10 +96,11 @@ public class OnlineUserController extends Handler {
|
||||
MainContext.AgentUserStatusEnum.END.toString())));
|
||||
|
||||
AgentService agentService = agentServiceList.get(0);
|
||||
if(!StringUtils.isBlank(agentservice)){
|
||||
if (StringUtils.isNotBlank(agentservice)) {
|
||||
for (AgentService as : agentServiceList) {
|
||||
if (as.getId().equals(agentservice)) {
|
||||
agentService = as ; break ;
|
||||
agentService = as;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +151,7 @@ public class OnlineUserController extends Handler {
|
||||
|
||||
map.put("curAgentService", agentService);
|
||||
map.put("curragentuser", curragentuser);
|
||||
if(!StringUtils.isBlank(title)){
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
map.put("title", title);
|
||||
}
|
||||
|
||||
@ -186,7 +171,7 @@ public class OnlineUserController extends Handler {
|
||||
@RequestMapping("/trace")
|
||||
@Menu(type = "service", subtype = "trace", admin = false)
|
||||
public ModelAndView trace(ModelMap map, HttpServletRequest request, @Valid String sessionid) {
|
||||
if(!StringUtils.isBlank(sessionid)){
|
||||
if (StringUtils.isNotBlank(sessionid)) {
|
||||
map.addAttribute("traceHisList", userEventRes.findBySessionidAndOrgi(sessionid, super.getOrgi(request), new PageRequest(0, 100)));
|
||||
}
|
||||
return request(super.createRequestPageTempletResponse("/apps/service/online/trace"));
|
||||
|
@ -16,26 +16,15 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.apps.setting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.AdTypeRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.SessionConfigRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TagRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.TemplateRepository;
|
||||
import com.chatopera.cc.app.model.AdType;
|
||||
import com.chatopera.cc.app.model.SysDic;
|
||||
import com.chatopera.cc.app.model.Tag;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.blob.JpaBlobHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -43,17 +32,16 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.app.persistence.repository.BlackListRepository;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.BlackEntity;
|
||||
import com.chatopera.cc.app.model.SessionConfig;
|
||||
import com.chatopera.cc.app.model.UKeFuDic;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/setting")
|
||||
@ -74,6 +62,13 @@ public class IMAgentController extends Handler{
|
||||
@Autowired
|
||||
private TemplateRepository templateRes;
|
||||
|
||||
|
||||
@Autowired
|
||||
private StreamingFileRepository streamingFileRes;
|
||||
|
||||
@Autowired
|
||||
private JpaBlobHelper jpaBlobHelper;
|
||||
|
||||
@Value("${web.upload-path}")
|
||||
private String path;
|
||||
|
||||
@ -128,7 +123,6 @@ public class IMAgentController extends Handler{
|
||||
map.put("sessionConfig", tempSessionConfig);
|
||||
|
||||
|
||||
|
||||
return request(super.createRequestPageTempletResponse("redirect:/setting/agent/index.html"));
|
||||
}
|
||||
|
||||
@ -224,7 +218,6 @@ public class IMAgentController extends Handler{
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/acd")
|
||||
@Menu(type = "setting", subtype = "acd", admin = false)
|
||||
public ModelAndView acd(ModelMap map, HttpServletRequest request) {
|
||||
@ -273,18 +266,12 @@ public class IMAgentController extends Handler{
|
||||
public ModelAndView advsave(ModelMap map, HttpServletRequest request, @Valid AdType adv, @Valid String advtype, @RequestParam(value = "imgfile", required = false) MultipartFile imgfile) throws IOException {
|
||||
adv.setOrgi(super.getOrgi(request));
|
||||
adv.setCreater(super.getUser(request).getId());
|
||||
if(!StringUtils.isBlank(adv.getContent())){
|
||||
if (StringUtils.isNotBlank(adv.getContent())) {
|
||||
adv.setContent(adv.getContent().replaceAll("\"", "'"));
|
||||
}
|
||||
adv.setCreatetime(new Date());
|
||||
if (imgfile != null && imgfile.getSize() > 0) {
|
||||
File adDir = new File(path , "adv");
|
||||
if(!adDir.exists()){
|
||||
adDir.mkdirs() ;
|
||||
}
|
||||
String fileName = "adv/"+ MainUtils.getUUID()+imgfile.getOriginalFilename().substring(imgfile.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileCopyUtils.copy(imgfile.getBytes(), new File(path , fileName));
|
||||
adv.setImgurl("/res/image.html?id="+java.net.URLEncoder.encode(fileName , "UTF-8"));
|
||||
adv.setImgurl("/res/image.html?id=" + super.saveImageFileWithMultipart(imgfile));
|
||||
}
|
||||
adTypeRes.save(adv);
|
||||
|
||||
@ -309,17 +296,11 @@ public class IMAgentController extends Handler{
|
||||
ad.setOrgi(super.getOrgi(request));
|
||||
ad.setCreater(tempad.getCreater());
|
||||
ad.setCreatetime(tempad.getCreatetime());
|
||||
if(!StringUtils.isBlank(ad.getContent())){
|
||||
if (StringUtils.isNotBlank(ad.getContent())) {
|
||||
ad.setContent(ad.getContent().replaceAll("\"", "'"));
|
||||
}
|
||||
if (imgfile != null && imgfile.getSize() > 0) {
|
||||
File adDir = new File(path , "adv");
|
||||
if(!adDir.exists()){
|
||||
adDir.mkdirs() ;
|
||||
}
|
||||
String fileName = "adv/"+ MainUtils.getUUID()+imgfile.getOriginalFilename().substring(imgfile.getOriginalFilename().lastIndexOf(".")) ;
|
||||
FileCopyUtils.copy(imgfile.getBytes(), new File(path , fileName));
|
||||
ad.setImgurl("/res/image.html?id="+java.net.URLEncoder.encode(fileName , "UTF-8"));
|
||||
ad.setImgurl("/res/image.html?id=" + super.saveImageFileWithMultipart(imgfile));
|
||||
} else {
|
||||
ad.setImgurl(tempad.getImgurl());
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class TestController extends Handler {
|
||||
for(int i=0 ; i<500; i++){
|
||||
String user = MainUtils.getUUID();
|
||||
try {
|
||||
OnlineUserUtils.newRequestMessage(user, "ukewo", "user", "system", "localhost" , "win10", "test" , MainContext.ChannelTypeEnum.WEBIM.toString() , null , null , "admin" , "标题" , "http://www.ukewo.cn" , "12434" , MainContext.ChatInitiatorType.USER.toString()) ;
|
||||
OnlineUserUtils.newRequestMessage(user, "ukewo", "user", "system", "localhost" , "win10", "test" , MainContext.ChannelTypeEnum.WEBIM.toString() , null , null , "admin" , "标题" , "https://www.chatopera.com" , "12434" , MainContext.ChatInitiatorType.USER.toString()) ;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -16,42 +16,53 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.handler.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.AttachmentFile;
|
||||
import com.chatopera.cc.app.model.StreamingFile;
|
||||
import com.chatopera.cc.app.model.UploadStatus;
|
||||
import com.chatopera.cc.app.persistence.blob.JpaBlobHelper;
|
||||
import com.chatopera.cc.app.persistence.repository.AttachmentRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.StreamingFileRepository;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.persistence.repository.AttachmentRepository;
|
||||
import com.chatopera.cc.app.handler.Handler;
|
||||
import com.chatopera.cc.app.model.AttachmentFile;
|
||||
import com.chatopera.cc.app.model.UploadStatus;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/res")
|
||||
public class MediaController extends Handler {
|
||||
private final static Logger logger = LoggerFactory.getLogger(MediaController.class);
|
||||
|
||||
@Value("${web.upload-path}")
|
||||
private String path;
|
||||
|
||||
@Autowired
|
||||
private StreamingFileRepository streamingFileRes;
|
||||
|
||||
@Autowired
|
||||
private JpaBlobHelper jpaBlobHelper;
|
||||
|
||||
private String TEMPLATE_DATA_PATH = "WEB-INF/data/templates/";
|
||||
|
||||
@Autowired
|
||||
@ -59,31 +70,25 @@ public class MediaController extends Handler{
|
||||
|
||||
@RequestMapping("/image")
|
||||
@Menu(type = "resouce", subtype = "image", access = true)
|
||||
public void index(HttpServletResponse response, @Valid String id) throws IOException {
|
||||
File file = new File(path ,id) ;
|
||||
if(!StringUtils.isBlank(id) && !(id.endsWith(".png") || id.endsWith(".jpg"))){
|
||||
if(id.endsWith("_original") && !file.exists()){
|
||||
File orgFile = new File(path , id.substring(0 , id.indexOf("_original"))) ;
|
||||
if(orgFile.exists()){
|
||||
MainUtils.processImage(file = new File(path , id), orgFile) ;
|
||||
public void index(HttpServletResponse response,
|
||||
@Valid String id,
|
||||
@RequestParam(value = "original", required = false) boolean original,
|
||||
@RequestParam(value = "cooperation", required = false) boolean cooperation) throws IOException, SQLException {
|
||||
StreamingFile sf = streamingFileRes.findOne(id);
|
||||
if (sf != null) {
|
||||
response.setHeader("Content-Type", sf.getMime());
|
||||
response.setContentType(sf.getMime());
|
||||
if (cooperation && (sf.getCooperation() != null)) { // 协作文件
|
||||
IOUtils.copy(sf.getCooperation().getBinaryStream(), response.getOutputStream());
|
||||
} else if (original && sf.getData() != null) { // 源文件
|
||||
IOUtils.copy(sf.getData().getBinaryStream(), response.getOutputStream());
|
||||
} else if (sf.getThumbnail() != null) { // 缩略图
|
||||
IOUtils.copy(sf.getThumbnail().getBinaryStream(), response.getOutputStream());
|
||||
} else if (sf.getData() != null) {
|
||||
IOUtils.copy(sf.getData().getBinaryStream(), response.getOutputStream());
|
||||
} else {
|
||||
logger.warn("[index] can not get streaming file id {}, original {}, cooperation {}", id, original, cooperation);
|
||||
}
|
||||
}else if(!StringUtils.isBlank(id) && file.exists() && !id.endsWith("_original")){
|
||||
File originalFile = new File( path , id+"_original") ;
|
||||
if(!originalFile.exists()){
|
||||
MainUtils.processImage(new File( path , id+"_original"), file) ;
|
||||
}
|
||||
}else if(!StringUtils.isBlank(id) && !file.exists() && !id.endsWith("_original")){
|
||||
File destFile = new File(path , id+"_original") ;
|
||||
if(destFile.exists()){
|
||||
MainUtils.processImage(new File(path + id), destFile) ;
|
||||
}
|
||||
file = new File(path , id) ;
|
||||
}
|
||||
}
|
||||
if(file.exists() && file.isFile()){
|
||||
response.setHeader("Content-Type","image/png");
|
||||
response.setContentType("image/png");
|
||||
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path ,id)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +107,7 @@ public class MediaController extends Handler{
|
||||
byte[] data = new byte[1024];
|
||||
int length = 0;
|
||||
OutputStream out = response.getOutputStream();
|
||||
if(!StringUtils.isBlank(url)){
|
||||
if (StringUtils.isNotBlank(url)) {
|
||||
InputStream input = new URL(url).openStream();
|
||||
while ((length = input.read(data)) > 0) {
|
||||
out.write(data, 0, length);
|
||||
@ -113,52 +118,56 @@ public class MediaController extends Handler{
|
||||
|
||||
@RequestMapping("/image/upload")
|
||||
@Menu(type = "resouce", subtype = "imageupload", access = false)
|
||||
public ModelAndView upload(ModelMap map,HttpServletRequest request , @RequestParam(value = "imgFile", required = false) MultipartFile imgFile) throws IOException {
|
||||
public ModelAndView upload(ModelMap map,
|
||||
HttpServletRequest request,
|
||||
@RequestParam(value = "imgFile", required = false) MultipartFile multipart) throws IOException {
|
||||
ModelAndView view = request(super.createRequestPageTempletResponse("/public/upload"));
|
||||
UploadStatus upload = null ;
|
||||
String fileName = null ;
|
||||
if(imgFile!=null && imgFile.getOriginalFilename().lastIndexOf(".") > 0){
|
||||
UploadStatus notify = null;
|
||||
if (multipart != null && multipart.getOriginalFilename().lastIndexOf(".") > 0) {
|
||||
File uploadDir = new File(path, "upload");
|
||||
if (!uploadDir.exists()) {
|
||||
uploadDir.mkdirs();
|
||||
}
|
||||
fileName = "upload/"+ MainUtils.md5(imgFile.getBytes())+imgFile.getOriginalFilename().substring(imgFile.getOriginalFilename().lastIndexOf(".")).toLowerCase() ;
|
||||
FileCopyUtils.copy(imgFile.getBytes(), new File(path , fileName));
|
||||
|
||||
String fileURL = request.getScheme()+"://"+request.getServerName()+"/res/image.html?id="+fileName ;
|
||||
if(request.getServerPort() == 80){
|
||||
fileURL = request.getScheme()+"://"+request.getServerName()+"/res/image.html?id="+fileName;
|
||||
String fileid = MainUtils.getUUID();
|
||||
StreamingFile sf = new StreamingFile();
|
||||
sf.setId(fileid);
|
||||
sf.setName(multipart.getOriginalFilename());
|
||||
sf.setMime(multipart.getContentType());
|
||||
sf.setData(jpaBlobHelper.createBlob(multipart.getInputStream(), multipart.getSize()));
|
||||
streamingFileRes.save(sf);
|
||||
String fileURL = "/res/image.html?id=" + fileid;
|
||||
notify = new UploadStatus("0", fileURL); //图片直接发送给 客户,不用返回
|
||||
} else {
|
||||
fileURL = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/res/image.html?id="+fileName;
|
||||
notify = new UploadStatus("请选择图片文件");
|
||||
}
|
||||
upload = new UploadStatus("0" , fileURL); //图片直接发送给 客户,不用返回
|
||||
}else{
|
||||
upload = new UploadStatus("请选择图片文件");
|
||||
}
|
||||
map.addAttribute("upload", upload) ;
|
||||
map.addAttribute("upload", notify);
|
||||
return view;
|
||||
}
|
||||
|
||||
@RequestMapping("/file")
|
||||
@Menu(type = "resouce", subtype = "file", access = false)
|
||||
public void file(HttpServletResponse response,HttpServletRequest request, @Valid String id) throws IOException {
|
||||
if(!StringUtils.isBlank(id)){
|
||||
public void file(HttpServletResponse response, HttpServletRequest request, @Valid String id) throws IOException, SQLException {
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
AttachmentFile attachmentFile = attachementRes.findByIdAndOrgi(id, super.getOrgi(request));
|
||||
if(attachmentFile!=null){
|
||||
if (attachmentFile != null && attachmentFile.getFileid() != null) {
|
||||
StreamingFile sf = streamingFileRes.findOne(attachmentFile.getFileid());
|
||||
if (sf != null) {
|
||||
response.setContentType(attachmentFile.getFiletype());
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(attachmentFile.getTitle(), "UTF-8"));
|
||||
if(!StringUtils.isBlank(attachmentFile.getModel()) && attachmentFile.getModel().equals("app")){
|
||||
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path , "app/app/"+attachmentFile.getFileid())));
|
||||
IOUtils.copy(sf.getData().getBinaryStream(), response.getOutputStream());
|
||||
} else {
|
||||
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path , "app/workorders/"+attachmentFile.getFileid())));
|
||||
}
|
||||
logger.warn("[streaming file] can not get file id {}", attachmentFile.getFileid());
|
||||
}
|
||||
} else {
|
||||
logger.warn("[attachment file] can not find attachment file id {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/template")
|
||||
@Menu(type = "resouce", subtype = "template", access = false)
|
||||
public void template(HttpServletResponse response, HttpServletRequest request, @Valid String filename) throws IOException {
|
||||
if(!StringUtils.isBlank(filename)){
|
||||
if (StringUtils.isNotBlank(filename)) {
|
||||
InputStream is = MediaController.class.getClassLoader().getResourceAsStream(TEMPLATE_DATA_PATH + filename);
|
||||
if (is != null) {
|
||||
response.setContentType("text/plain");
|
||||
|
@ -16,13 +16,20 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.im.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.corundumstudio.socketio.SocketIOClient;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.im.util.IMServiceUtils;
|
||||
import com.chatopera.cc.app.schedule.WebIMAgentDispatcher;
|
||||
import com.chatopera.cc.app.schedule.WebIMOnlineUserDispatcher;
|
||||
import com.corundumstudio.socketio.SocketIOClient;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class NettyClients {
|
||||
|
||||
@ -48,9 +55,13 @@ public class NettyClients {
|
||||
return this.callCenterClients;
|
||||
}
|
||||
|
||||
/**
|
||||
* 访客连接
|
||||
*/
|
||||
public void setImClients(NettyIMClient imClients) {
|
||||
this.imClients = imClients;
|
||||
}
|
||||
|
||||
public void putIMEventClient(String id, SocketIOClient userClient) {
|
||||
imClients.putClient(id, userClient);
|
||||
}
|
||||
@ -63,47 +74,97 @@ public class NettyClients {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIMEventClient(String id, String sessionid) {
|
||||
imClients.removeClient(id, sessionid);
|
||||
}
|
||||
public void sendIMEventMessage(String id , String event , Object data){
|
||||
|
||||
public void publishIMEventMessage(final String id, final String event, Serializable data) {
|
||||
// 检测client是否在这台机器上
|
||||
if (!sendIMEventMessage(id, event, data)) {
|
||||
try {
|
||||
JsonObject payload = new JsonObject();
|
||||
payload.addProperty("event", event);
|
||||
payload.addProperty("id", id);
|
||||
payload.addProperty("data", IMServiceUtils.serialize(data));
|
||||
MainContext.getContext().getBean(WebIMOnlineUserDispatcher.class).publish(payload);
|
||||
} catch (IOException e) {
|
||||
logger.error("publishIMEventMessage", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendIMEventMessage(final String id, final String event, Object data) {
|
||||
List<SocketIOClient> userClients = imClients.getClients(id);
|
||||
for (SocketIOClient userClient : userClients) {
|
||||
userClient.sendEvent(event, data);
|
||||
}
|
||||
return userClients.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 坐席连接
|
||||
*/
|
||||
public void setAgentClients(NettyAgentClient agentClients) {
|
||||
this.agentClients = agentClients;
|
||||
}
|
||||
|
||||
public void putAgentEventClient(String id, SocketIOClient agentClient) {
|
||||
agentClients.putClient(id, agentClient);
|
||||
}
|
||||
|
||||
public void removeAgentEventClient(String id, String sessionid) {
|
||||
agentClients.removeClient(id, sessionid);
|
||||
}
|
||||
public void sendAgentEventMessage(String id , String event , Object data){
|
||||
|
||||
// publish to Redis
|
||||
public void publishAgentEventMessage(String id, String event, Serializable data) {
|
||||
// 检测client是否在这台机器上
|
||||
if (!sendAgentEventMessage(id, event, data)) {
|
||||
try {
|
||||
JsonObject payload = new JsonObject();
|
||||
payload.addProperty("event", event);
|
||||
payload.addProperty("id", id);
|
||||
payload.addProperty("data", IMServiceUtils.serialize(data));
|
||||
MainContext.getContext().getBean(WebIMAgentDispatcher.class).publish(payload);
|
||||
} catch (IOException e) {
|
||||
logger.error("publishAgentEventMessage", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 向坐席发送消息
|
||||
public boolean sendAgentEventMessage(String id, String event, Object data) {
|
||||
List<SocketIOClient> agents = agentClients.getClients(id);
|
||||
for (SocketIOClient agentClient : agents) {
|
||||
agentClient.sendEvent(event, data);
|
||||
}
|
||||
|
||||
return agents.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业聊天
|
||||
*/
|
||||
public void setEntImClients(NettyIMClient entIMClients) {
|
||||
this.entIMClients = entIMClients;
|
||||
}
|
||||
|
||||
public void putEntIMEventClient(String id, SocketIOClient userClient) {
|
||||
entIMClients.putClient(id, userClient);
|
||||
}
|
||||
|
||||
public void removeEntIMEventClient(String id, String sessionid) {
|
||||
entIMClients.removeClient(id, sessionid);
|
||||
}
|
||||
|
||||
public void sendEntIMEventMessage(String id, String event, Object data) {
|
||||
List<SocketIOClient> entims = entIMClients.getClients(id);
|
||||
for (SocketIOClient userClient : entims) {
|
||||
userClient.sendEvent(event, data);
|
||||
}
|
||||
}
|
||||
|
||||
public int getEntIMClientsNum(String user) {
|
||||
return entIMClients.getClients(user) != null ? entIMClients.getClients(user).size() : 0;
|
||||
}
|
||||
@ -115,6 +176,25 @@ public class NettyClients {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callout Event Server Methods.
|
||||
*/
|
||||
public void putCalloutEventClient(String id, SocketIOClient client) {
|
||||
calloutClients.putClient(id, client);
|
||||
}
|
||||
|
||||
public void removeCalloutEventClient(String id, String sessionId) {
|
||||
calloutClients.removeClient(id, sessionId);
|
||||
}
|
||||
|
||||
public void sendCalloutEventMessage(String id, String event, Object data) {
|
||||
List<SocketIOClient> _clients = calloutClients.getClients(id);
|
||||
logger.info("sendCalloutEventMessage get clients size {}", _clients.size());
|
||||
for (SocketIOClient c : _clients) {
|
||||
c.sendEvent(event, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Chatbot Event Server Methods.
|
||||
@ -135,23 +215,4 @@ public class NettyClients {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callout Event Server Methods.
|
||||
*/
|
||||
public void putCalloutEventClient(String id, SocketIOClient client){
|
||||
calloutClients.putClient(id, client);
|
||||
}
|
||||
|
||||
public void removeCalloutEventClient(String id, String sessionId) {
|
||||
calloutClients.removeClient(id, sessionId);
|
||||
}
|
||||
|
||||
public void sendCalloutEventMessage(String id, String event, Object data){
|
||||
List<SocketIOClient> _clients = calloutClients.getClients(id);
|
||||
logger.info("sendCalloutEventMessage get clients size {}", _clients.size());
|
||||
for(SocketIOClient c: _clients){
|
||||
c.sendEvent(event, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,57 +16,45 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.im.handler;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.message.AgentServiceMessage;
|
||||
import com.chatopera.cc.app.im.message.AgentStatusMessage;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.corundumstudio.socketio.AckRequest;
|
||||
import com.corundumstudio.socketio.SocketIOClient;
|
||||
import com.corundumstudio.socketio.SocketIOServer;
|
||||
import com.corundumstudio.socketio.annotation.OnConnect;
|
||||
import com.corundumstudio.socketio.annotation.OnDisconnect;
|
||||
import com.corundumstudio.socketio.annotation.OnEvent;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentStatusRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserTaskRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ChatMessageRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.WorkSessionRepository;
|
||||
import com.chatopera.cc.app.model.AgentStatus;
|
||||
import com.chatopera.cc.app.model.AgentUser;
|
||||
import com.chatopera.cc.app.model.AgentUserTask;
|
||||
import com.chatopera.cc.app.model.MessageOutContent;
|
||||
import com.chatopera.cc.app.model.WorkSession;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class AgentEventHandler
|
||||
{
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class AgentEventHandler {
|
||||
protected SocketIOServer server;
|
||||
|
||||
@Autowired
|
||||
public AgentEventHandler(SocketIOServer server)
|
||||
{
|
||||
public AgentEventHandler(SocketIOServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@OnConnect
|
||||
public void onConnect(SocketIOClient client)
|
||||
{
|
||||
public void onConnect(SocketIOClient client) {
|
||||
String user = client.getHandshakeData().getSingleUrlParam("userid");
|
||||
String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
|
||||
String session = client.getHandshakeData().getSingleUrlParam("session");
|
||||
String admin = client.getHandshakeData().getSingleUrlParam("admin");
|
||||
if(!StringUtils.isBlank(user) && !StringUtils.isBlank(user)){
|
||||
if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(user)) {
|
||||
client.set("agentno", user);
|
||||
AgentStatusRepository agentStatusRepository = MainContext.getContext().getBean(AgentStatusRepository.class);
|
||||
List<AgentStatus> agentStatusList = agentStatusRepository.findByAgentnoAndOrgi(user, orgi);
|
||||
@ -93,13 +81,12 @@ public class AgentEventHandler
|
||||
|
||||
//添加@OnDisconnect事件,客户端断开连接时调用,刷新客户端信息
|
||||
@OnDisconnect
|
||||
public void onDisconnect(SocketIOClient client)
|
||||
{
|
||||
public void onDisconnect(SocketIOClient client) {
|
||||
String user = client.getHandshakeData().getSingleUrlParam("userid");
|
||||
String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
|
||||
String admin = client.getHandshakeData().getSingleUrlParam("admin");
|
||||
if(!StringUtils.isBlank(user)){
|
||||
AutomaticServiceDist.deleteAgentStatus(user, orgi, !StringUtils.isBlank(admin) && admin.equals("true"));
|
||||
if (StringUtils.isNotBlank(user)) {
|
||||
AutomaticServiceDist.deleteAgentStatus(user, orgi, StringUtils.isNotBlank(admin) && admin.equals("true"));
|
||||
NettyClients.getInstance().removeAgentEventClient(user, MainUtils.getContextID(client.getSessionId().toString()));
|
||||
|
||||
WorkSessionRepository workSessionRepository = MainContext.getContext().getBean(WorkSessionRepository.class);
|
||||
@ -122,22 +109,19 @@ public class AgentEventHandler
|
||||
|
||||
//消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息
|
||||
@OnEvent(value = "service")
|
||||
public void onEvent(SocketIOClient client, AckRequest request, AgentServiceMessage data)
|
||||
{
|
||||
public void onEvent(SocketIOClient client, AckRequest request, AgentServiceMessage data) {
|
||||
|
||||
}
|
||||
|
||||
//消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息
|
||||
@OnEvent(value = "status")
|
||||
public void onEvent(SocketIOClient client, AckRequest request, AgentStatusMessage data)
|
||||
{
|
||||
public void onEvent(SocketIOClient client, AckRequest request, AgentStatusMessage data) {
|
||||
|
||||
}
|
||||
|
||||
//消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息
|
||||
@OnEvent(value = "message")
|
||||
public void onEvent(SocketIOClient client, AckRequest request, ChatMessage data)
|
||||
{
|
||||
public void onEvent(SocketIOClient client, AckRequest request, ChatMessage data) {
|
||||
String user = client.getHandshakeData().getSingleUrlParam("userid");
|
||||
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(data.getTouser(), data.getOrgi());
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
@ -178,7 +162,7 @@ public class AgentEventHandler
|
||||
}
|
||||
|
||||
data.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
if(!StringUtils.isBlank(agentUser.getAgentno())){
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentno())) {
|
||||
data.setTouser(agentUser.getUserid());
|
||||
}
|
||||
data.setChannel(agentUser.getChannel());
|
||||
@ -229,7 +213,7 @@ public class AgentEventHandler
|
||||
|
||||
client.sendEvent(MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
|
||||
if(!StringUtils.isBlank(data.getTouser())){
|
||||
if (StringUtils.isNotBlank(data.getTouser())) {
|
||||
OutMessageRouter router = null;
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
if (router != null) {
|
||||
|
@ -51,7 +51,7 @@ public class CalloutEventHandler
|
||||
String admin = client.getHandshakeData().getSingleUrlParam("admin") ;
|
||||
logger.info("onConnect userid {}, orgi {}.", user, orgi);
|
||||
|
||||
if(!StringUtils.isBlank(user) && !StringUtils.isBlank(user)){
|
||||
if(StringUtils.isNotBlank(user) && StringUtils.isNotBlank(user)){
|
||||
client.set("agentno", user);
|
||||
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress() ;
|
||||
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString()) ;
|
||||
|
@ -24,6 +24,7 @@ import com.chatopera.cc.app.im.message.AgentStatusMessage;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import com.chatopera.cc.app.im.message.NewRequestMessage;
|
||||
import com.chatopera.cc.app.im.util.ChatbotUtils;
|
||||
import com.chatopera.cc.app.im.util.IMServiceUtils;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ChatbotRepository;
|
||||
@ -65,6 +66,7 @@ public class ChatbotEventHandler {
|
||||
@OnConnect
|
||||
public void onConnect(SocketIOClient client) {
|
||||
try {
|
||||
|
||||
String user = client.getHandshakeData().getSingleUrlParam("userid");
|
||||
String nickname = client.getHandshakeData().getSingleUrlParam("nickname");
|
||||
String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
|
||||
@ -73,6 +75,7 @@ public class ChatbotEventHandler {
|
||||
String aiid = client.getHandshakeData().getSingleUrlParam("aiid");
|
||||
// String agent = client.getHandshakeData().getSingleUrlParam("agent") ;
|
||||
// String skill = client.getHandshakeData().getSingleUrlParam("skill") ;
|
||||
logger.info("onConnect userid {}, nickname {}", user, nickname);
|
||||
Date now = new Date();
|
||||
|
||||
if (StringUtils.isNotBlank(user)) {
|
||||
@ -80,21 +83,40 @@ public class ChatbotEventHandler {
|
||||
* 加入到 缓存列表
|
||||
*/
|
||||
NettyClients.getInstance().putChatbotEventClient(user, client);
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
CousultInvite invite = OnlineUserUtils.cousult(appid, orgi, MainContext.getContext().getBean(ConsultInviteRepository.class));
|
||||
|
||||
/**
|
||||
* 更新坐席服务类型
|
||||
*/
|
||||
IMServiceUtils.shiftOpsType(user, orgi, MainContext.OptTypeEnum.CHATBOT);
|
||||
|
||||
// send out tip
|
||||
MessageOutContent tip = new MessageOutContent();
|
||||
tip.setMessage("您正在使用机器人客服!");
|
||||
tip.setMessageType(MainContext.MessageTypeEnum.MESSAGE.toString());
|
||||
tip.setCalltype(MainContext.CallTypeEnum.IN.toString());
|
||||
tip.setNickName(invite.getAiname());
|
||||
tip.setCreatetime(MainUtils.dateFormate.format(now));
|
||||
|
||||
client.sendEvent(MainContext.MessageTypeEnum.STATUS.toString(), tip);
|
||||
|
||||
// send out welcome message
|
||||
if (invite != null && StringUtils.isNotBlank(invite.getAisuccesstip())) {
|
||||
outMessage.setMessage(invite.getAisuccesstip());
|
||||
} else {
|
||||
outMessage.setMessage("欢迎使用华夏春松机器人客服!");
|
||||
ChatMessage welcome = new ChatMessage();
|
||||
welcome.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
welcome.setAppid(appid);
|
||||
welcome.setOrgi(orgi);
|
||||
welcome.setAiid(aiid);
|
||||
welcome.setMessage(invite.getAisuccesstip());
|
||||
welcome.setTouser(user);
|
||||
welcome.setTousername(nickname);
|
||||
welcome.setMsgtype(MainContext.MessageTypeEnum.MESSAGE.toString());
|
||||
welcome.setUserid(user);
|
||||
welcome.setUsername(invite.getAiname());
|
||||
welcome.setUpdatetime(System.currentTimeMillis());
|
||||
client.sendEvent(MainContext.MessageTypeEnum.MESSAGE.toString(), welcome);
|
||||
}
|
||||
|
||||
outMessage.setMessageType(MainContext.MessageTypeEnum.MESSAGE.toString());
|
||||
outMessage.setCalltype(MainContext.CallTypeEnum.IN.toString());
|
||||
outMessage.setNickName(invite.getAiname());
|
||||
outMessage.setCreatetime(MainUtils.dateFormate.format(now));
|
||||
|
||||
client.sendEvent(MainContext.MessageTypeEnum.STATUS.toString(), outMessage);
|
||||
|
||||
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
|
||||
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
|
||||
OnlineUser onlineUser = getOnlineUserRes().findOne(user);
|
||||
@ -139,6 +161,7 @@ public class ChatbotEventHandler {
|
||||
agentUser.setCreatetime(now);
|
||||
agentUser.setUpdatetime(now);
|
||||
agentUser.setSessionid(session);
|
||||
agentUser.setRegion(onlineUser.getRegion());
|
||||
|
||||
// 聊天机器人处理的请求
|
||||
agentUser.setOpttype(MainContext.OptTypeEnum.CHATBOT.toString());
|
||||
@ -146,7 +169,7 @@ public class ChatbotEventHandler {
|
||||
agentUser.setCity(onlineUser.getCity());
|
||||
agentUser.setProvince(onlineUser.getProvince());
|
||||
agentUser.setCountry(onlineUser.getCountry());
|
||||
AgentService agentService = AutomaticServiceDist.processChatbotService(agentUser, orgi);
|
||||
AgentService agentService = AutomaticServiceDist.processChatbotService(invite != null ? invite.getAiname() : "机器人客服", agentUser, orgi);
|
||||
agentUser.setAgentserviceid(agentService.getId());
|
||||
|
||||
// 标记为机器人坐席
|
||||
@ -172,7 +195,7 @@ public class ChatbotEventHandler {
|
||||
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(user, orgi);
|
||||
OnlineUser onlineUser = (OnlineUser) CacheHelper.getOnlineUserCacheBean().getCacheObject(user, orgi);
|
||||
if (agentUser != null) {
|
||||
AutomaticServiceDist.processChatbotService(agentUser, orgi);
|
||||
AutomaticServiceDist.processChatbotService(null, agentUser, orgi);
|
||||
CacheHelper.getAgentUserCacheBean().delete(user, MainContext.SYSTEM_ORGI);
|
||||
CacheHelper.getOnlineUserCacheBean().delete(user, orgi);
|
||||
agentUser.setStatus(MainContext.OnlineUserOperatorStatus.OFFLINE.toString());
|
||||
|
@ -25,6 +25,7 @@ import com.chatopera.cc.app.im.message.AgentStatusMessage;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import com.chatopera.cc.app.im.message.NewRequestMessage;
|
||||
import com.chatopera.cc.app.im.util.HumanUtils;
|
||||
import com.chatopera.cc.app.im.util.IMServiceUtils;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.impl.AgentUserService;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentServiceRepository;
|
||||
@ -37,6 +38,8 @@ import com.corundumstudio.socketio.annotation.OnConnect;
|
||||
import com.corundumstudio.socketio.annotation.OnDisconnect;
|
||||
import com.corundumstudio.socketio.annotation.OnEvent;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -45,6 +48,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class IMEventHandler {
|
||||
private final static Logger logger = LoggerFactory.getLogger(IMEventHandler.class);
|
||||
protected SocketIOServer server;
|
||||
|
||||
@Autowired
|
||||
@ -68,19 +72,40 @@ public class IMEventHandler {
|
||||
|
||||
String nickname = client.getHandshakeData().getSingleUrlParam("nickname");
|
||||
|
||||
if (!StringUtils.isBlank(user)) {
|
||||
if (StringUtils.isNotBlank(user)) {
|
||||
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
|
||||
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
|
||||
|
||||
/**
|
||||
* 加入到 缓存列表
|
||||
*/
|
||||
NettyClients.getInstance().putIMEventClient(user, client);
|
||||
|
||||
/**
|
||||
* 更新坐席服务类型
|
||||
*/
|
||||
IMServiceUtils.shiftOpsType(user, orgi, MainContext.OptTypeEnum.HUMAN);
|
||||
|
||||
/**
|
||||
* 用户进入到对话连接 , 排队用户请求 , 如果返回失败,表示当前坐席全忙,用户进入排队状态,当前提示信息 显示 当前排队的队列位置,不可进行对话,用户发送的消息作为留言处理
|
||||
*/
|
||||
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
|
||||
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
|
||||
NewRequestMessage newRequestMessage = OnlineUserUtils.newRequestMessage(user, orgi, session, appid, ip, client.getHandshakeData().getSingleUrlParam("osname"), client.getHandshakeData().getSingleUrlParam("browser"), MainContext.ChannelTypeEnum.WEBIM.toString(), skill, agent, nickname, title, url, traceid, MainContext.ChatInitiatorType.USER.toString());
|
||||
// /**
|
||||
// * 加入到 缓存列表
|
||||
// */
|
||||
NettyClients.getInstance().putIMEventClient(user, client);
|
||||
//
|
||||
if (newRequestMessage != null && !StringUtils.isBlank(newRequestMessage.getMessage())) {
|
||||
NewRequestMessage newRequestMessage = OnlineUserUtils.newRequestMessage(user,
|
||||
orgi,
|
||||
session,
|
||||
appid,
|
||||
ip,
|
||||
client.getHandshakeData().getSingleUrlParam("osname"),
|
||||
client.getHandshakeData().getSingleUrlParam("browser"),
|
||||
MainContext.ChannelTypeEnum.WEBIM.toString(),
|
||||
skill,
|
||||
agent,
|
||||
nickname,
|
||||
title,
|
||||
url,
|
||||
traceid,
|
||||
MainContext.ChatInitiatorType.USER.toString());
|
||||
|
||||
if (newRequestMessage != null && StringUtils.isNotBlank(newRequestMessage.getMessage())) {
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
outMessage.setMessage(newRequestMessage.getMessage());
|
||||
outMessage.setMessageType(MainContext.MessageTypeEnum.MESSAGE.toString());
|
||||
@ -135,20 +160,19 @@ public class IMEventHandler {
|
||||
agentUser.setName(contacts.getName());
|
||||
agentUser.setPhone(contacts.getPhone());
|
||||
agentUser.setEmail(contacts.getEmail());
|
||||
agentUser.setResion(contacts.getMemo());
|
||||
agentUser.setChatbotops(false); // 非机器人客服
|
||||
agentUser.setOpttype(MainContext.OptTypeEnum.HUMAN.toString());
|
||||
service.save(agentUser);
|
||||
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, MainContext.SYSTEM_ORGI);
|
||||
}
|
||||
|
||||
AgentServiceRepository agentServiceRes = MainContext.getContext().getBean(AgentServiceRepository.class);
|
||||
List<AgentService> agentServiceList = agentServiceRes.findByUseridAndOrgi(user, orgi);
|
||||
List<AgentService> agentServiceList = agentServiceRes.findByUseridAndOrgiOrderByLogindateDesc(user, orgi);
|
||||
if (agentServiceList.size() > 0) {
|
||||
AgentService agentService = agentServiceList.get(0);
|
||||
agentService.setName(contacts.getName());
|
||||
agentService.setPhone(contacts.getName());
|
||||
agentService.setEmail(contacts.getName());
|
||||
agentService.setRegion(contacts.getMemo());
|
||||
agentService.setPhone(contacts.getPhone());
|
||||
agentService.setEmail(contacts.getEmail());
|
||||
agentServiceRes.save(agentService);
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,8 @@ public class MessageRouter extends Router{
|
||||
AgentService agentService = AutomaticServiceDist.allotAgent(inMessage.getAgentUser(), inMessage.getOrgi());
|
||||
if (agentService != null && MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(agentService.getStatus())) {
|
||||
outMessage.setMessage(AutomaticServiceDist.getSuccessMessage(agentService, inMessage.getAgentUser().getChannel(), inMessage.getOrgi()));
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), inMessage.getAgentUser());
|
||||
// TODO #111 publish to redis
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), inMessage.getAgentUser());
|
||||
} else {
|
||||
if (agentService.getQueneindex() > 0) { //当前有坐席
|
||||
outMessage.setMessage(AutomaticServiceDist.getQueneMessage(agentService.getQueneindex(), inMessage.getAgentUser().getChannel(), inMessage.getOrgi()));
|
||||
|
@ -32,7 +32,7 @@ public class WebIMOutMessageRouter implements OutMessageRouter{
|
||||
@Override
|
||||
public void handler(String touser, String msgtype, String appid,
|
||||
MessageOutContent outMessage) {
|
||||
NettyClients.getInstance().sendIMEventMessage(touser, msgtype, outMessage);
|
||||
NettyClients.getInstance().publishIMEventMessage(touser, msgtype, outMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -137,14 +137,14 @@ public class HumanUtils {
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) {
|
||||
NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
|
||||
NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
|
||||
if (statusMessage != null) {
|
||||
NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.STATUS.toString(), statusMessage);
|
||||
NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.STATUS.toString(), statusMessage);
|
||||
}
|
||||
}
|
||||
if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) {
|
||||
//将消息发送给 坐席
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
// TODO 将消息发送给 坐席
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ public class HumanUtils {
|
||||
// outMessage.setCreatetime(data.getCreatetime());
|
||||
//
|
||||
// if (!StringUtils.isBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) {
|
||||
// NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
|
||||
// NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
@ -0,0 +1,68 @@
|
||||
package com.chatopera.cc.app.im.util;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.model.AgentUser;
|
||||
import com.chatopera.cc.app.persistence.impl.AgentUserService;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Base64;
|
||||
|
||||
public class IMServiceUtils {
|
||||
private final static Logger logger = LoggerFactory.getLogger(IMServiceUtils.class);
|
||||
|
||||
public static void shiftOpsType(final String userId, final String orgi, final MainContext.OptTypeEnum opsType){
|
||||
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(userId, orgi);
|
||||
AgentUserService service = MainContext.getContext().getBean(
|
||||
AgentUserService.class);
|
||||
if (agentUser == null) {
|
||||
agentUser = service.findByUseridAndOrgi(userId, orgi);
|
||||
}
|
||||
if (agentUser != null) {
|
||||
switch (opsType){
|
||||
case CHATBOT:
|
||||
agentUser.setOpttype(MainContext.OptTypeEnum.CHATBOT.toString());
|
||||
agentUser.setChatbotops(true);
|
||||
break;
|
||||
case HUMAN:
|
||||
agentUser.setOpttype(MainContext.OptTypeEnum.HUMAN.toString());
|
||||
agentUser.setChatbotops(false);
|
||||
break;
|
||||
default:
|
||||
logger.warn("shiftOpsType unknown type.");
|
||||
break;
|
||||
}
|
||||
service.save(agentUser);
|
||||
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, orgi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the object to a Base64 string.
|
||||
*/
|
||||
public static String serialize(Serializable o) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(o);
|
||||
oos.close();
|
||||
return Base64.getEncoder().encodeToString(baos.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read the object from Base64 string.
|
||||
*/
|
||||
public static Object deserialize(String s) throws IOException,
|
||||
ClassNotFoundException {
|
||||
byte[] data = Base64.getDecoder().decode(s);
|
||||
ObjectInputStream ois = new ObjectInputStream(
|
||||
new ByteArrayInputStream(data));
|
||||
Object o = ois.readObject();
|
||||
ois.close();
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
@ -103,7 +103,7 @@ public class RichMediaUtils {
|
||||
data.setTouser(agentUser.getAgentno());
|
||||
data.setAppid(agentUser.getAppid());
|
||||
data.setOrgi(agentUser.getOrgi());
|
||||
if (StringUtils.equals(agentUser.getOpttype(), MainContext.OptTypeEnum.CHATBOT.toString())) {
|
||||
if (agentUser.isChatbotops()) {
|
||||
// TODO #75 create Chatbot Message
|
||||
// https://github.com/chatopera/cosin/issues/75
|
||||
logger.info("[createRichMediaMessageWithChannel] TODO #75 create Chatbot Message");
|
||||
|
@ -37,7 +37,7 @@ public class Chatbot {
|
||||
private String description;
|
||||
private String primaryLanguage;
|
||||
private String fallback;
|
||||
private String welcome;
|
||||
private String welcome; // 问候语
|
||||
private String baseUrl; // 智能问答引擎服务地址
|
||||
private String orgi; // 租户标识
|
||||
private String organ; // 组织机构
|
||||
|
@ -20,7 +20,7 @@ package com.chatopera.cc.app.model;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
|
||||
|
||||
public class MessageInContent implements MessageDataBean{
|
||||
public class MessageInContent implements MessageDataBean, java.io.Serializable {
|
||||
|
||||
public String id;
|
||||
private String nickName;
|
||||
@ -48,114 +48,151 @@ public class MessageInContent implements MessageDataBean{
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public String getOrgi() {
|
||||
return orgi;
|
||||
}
|
||||
|
||||
public void setOrgi(String orgi) {
|
||||
this.orgi = orgi;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessageType() {
|
||||
return messageType;
|
||||
}
|
||||
|
||||
public void setMessageType(String messageType) {
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public String getFromUser() {
|
||||
return fromUser;
|
||||
}
|
||||
|
||||
public void setFromUser(String fromUser) {
|
||||
this.fromUser = fromUser;
|
||||
}
|
||||
|
||||
public String getToUser() {
|
||||
return toUser;
|
||||
}
|
||||
|
||||
public void setToUser(String toUser) {
|
||||
this.toUser = toUser;
|
||||
}
|
||||
|
||||
public SNSAccount getSnsAccount() {
|
||||
return snsAccount;
|
||||
}
|
||||
|
||||
public void setSnsAccount(SNSAccount snsAccount) {
|
||||
this.snsAccount = snsAccount;
|
||||
}
|
||||
|
||||
public AgentUser getAgentUser() {
|
||||
return agentUser;
|
||||
}
|
||||
|
||||
public void setAgentUser(AgentUser agentUser) {
|
||||
this.agentUser = agentUser;
|
||||
}
|
||||
|
||||
public Object getChannelMessage() {
|
||||
return channelMessage;
|
||||
}
|
||||
|
||||
public void setChannelMessage(Object channelMessage) {
|
||||
this.channelMessage = channelMessage;
|
||||
}
|
||||
|
||||
public Object getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(Object user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getContextid() {
|
||||
return contextid;
|
||||
}
|
||||
|
||||
public void setContextid(String contextid) {
|
||||
this.contextid = contextid;
|
||||
}
|
||||
|
||||
public String getCalltype() {
|
||||
return calltype;
|
||||
}
|
||||
|
||||
public void setCalltype(String calltype) {
|
||||
this.calltype = calltype;
|
||||
}
|
||||
|
||||
public String getCreatetime() {
|
||||
return createtime;
|
||||
}
|
||||
|
||||
public void setCreatetime(String createtime) {
|
||||
this.createtime = createtime;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public int getFilesize() {
|
||||
return filesize;
|
||||
}
|
||||
|
||||
public void setFilesize(int filesize) {
|
||||
this.filesize = filesize;
|
||||
}
|
||||
|
||||
public String getAgentserviceid() {
|
||||
return agentserviceid;
|
||||
}
|
||||
|
||||
public void setAgentserviceid(String agentserviceid) {
|
||||
this.agentserviceid = agentserviceid;
|
||||
}
|
||||
|
||||
public String getAttachmentid() {
|
||||
return attachmentid;
|
||||
}
|
||||
|
||||
public void setAttachmentid(String attachmentid) {
|
||||
this.attachmentid = attachmentid;
|
||||
}
|
||||
|
||||
public boolean isNoagent() {
|
||||
return noagent;
|
||||
}
|
||||
|
||||
public void setNoagent(boolean noagent) {
|
||||
this.noagent = noagent;
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.app.model;
|
||||
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Proxy;
|
||||
|
||||
import java.sql.Blob;
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Entity
|
||||
@Table(name = "cs_stream_file")
|
||||
@Proxy(lazy = false)
|
||||
public class StreamingFile implements java.io.Serializable {
|
||||
|
||||
private String id;
|
||||
|
||||
@NotNull
|
||||
private String name;
|
||||
|
||||
private String mime; // Media Type over HTTP
|
||||
|
||||
@NotNull
|
||||
private Blob data;
|
||||
|
||||
private Blob thumbnail; // 图片缩略图
|
||||
|
||||
private Blob cooperation; // 图片协作图
|
||||
|
||||
@Id
|
||||
@Column(length = 32)
|
||||
@GeneratedValue(generator = "system-uuid")
|
||||
@GenericGenerator(name = "system-uuid", strategy = "assigned")
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(@NotNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Blob getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(@NotNull Blob data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Blob getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public void setThumbnail(Blob thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public String getMime() {
|
||||
return mime;
|
||||
}
|
||||
|
||||
public void setMime(String mime) {
|
||||
this.mime = mime;
|
||||
}
|
||||
|
||||
public Blob getCooperation() {
|
||||
return cooperation;
|
||||
}
|
||||
|
||||
public void setCooperation(Blob cooperation) {
|
||||
this.cooperation = cooperation;
|
||||
}
|
||||
}
|
@ -515,6 +515,10 @@ public class User implements java.io.Serializable{
|
||||
this.ordertype = ordertype;
|
||||
}
|
||||
|
||||
public boolean inMyorgans(final String organ){
|
||||
return myorgans.contains(organ);
|
||||
}
|
||||
|
||||
@Transient
|
||||
public HashSet<String> getMyorgans() {
|
||||
return myorgans;
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.app.persistence.blob;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Blob;
|
||||
|
||||
@Component
|
||||
@Transactional
|
||||
public class JpaBlobHelper {
|
||||
|
||||
private final SessionFactory sessionFactory;
|
||||
|
||||
@Autowired
|
||||
public JpaBlobHelper(EntityManagerFactory factory) {
|
||||
if (factory.unwrap(SessionFactory.class) == null) {
|
||||
throw new NullPointerException("factory is not a hibernate factory");
|
||||
}
|
||||
this.sessionFactory = factory.unwrap(SessionFactory.class);
|
||||
}
|
||||
|
||||
|
||||
public Blob createBlob(InputStream content, long size) {
|
||||
return sessionFactory.getCurrentSession().getLobHelper().createBlob(content, size);
|
||||
}
|
||||
|
||||
public Blob createBlobWithFile(final File file) throws FileNotFoundException {
|
||||
return createBlob(new FileInputStream(file), file.length());
|
||||
}
|
||||
|
||||
}
|
@ -31,7 +31,7 @@ public abstract interface AgentServiceRepository
|
||||
{
|
||||
public abstract AgentService findByIdAndOrgi(String paramString , String orgi);
|
||||
|
||||
public abstract List<AgentService> findByUseridAndOrgi(String paramString, String orgi);
|
||||
public abstract List<AgentService> findByUseridAndOrgiOrderByLogindateDesc(String paramString, String orgi);
|
||||
|
||||
public abstract Page<AgentService> findByOrgi(String orgi, Pageable paramPageable);
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.app.persistence.repository;
|
||||
|
||||
import com.chatopera.cc.app.model.StreamingFile;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface StreamingFileRepository extends JpaRepository<StreamingFile, String> {
|
||||
}
|
@ -91,6 +91,7 @@ public class CallOutPlanTask {
|
||||
|
||||
@Scheduled(fixedDelayString = "${cskefu.callout.watch.interval}") // 每分钟执行一次
|
||||
public void watch() {
|
||||
if(MainContext.isEnableCalloutModule()){
|
||||
logger.debug("[callout executor] check dialplan job running status ...");
|
||||
// load all jobs
|
||||
List<CallOutDialplan> dps = callOutDialplanRes.findByStatusAndIsarchive(MainContext.CallOutDialplanStatusEnum.RUNNING.toString(), false);
|
||||
@ -108,6 +109,7 @@ public class CallOutPlanTask {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Async("callOutTaskExecutor")
|
||||
@Transactional
|
||||
|
@ -55,8 +55,6 @@ import java.util.List;
|
||||
@Component
|
||||
public class CallOutWireTask implements MessageListener {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CallOutWireTask.class);
|
||||
private static final RedisSerializer<String> redisStringSerializer = new StringRedisSerializer();
|
||||
|
||||
|
||||
@Autowired
|
||||
private CallOutDialplanRepository callOutDialplanRes;
|
||||
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.app.schedule;
|
||||
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.util.IMServiceUtils;
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.ListOperations;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.*;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 坐席消息分发
|
||||
*/
|
||||
@Component
|
||||
public class WebIMAgentDispatcher implements MessageListener {
|
||||
private final static Logger logger = LoggerFactory.getLogger(WebIMAgentDispatcher.class);
|
||||
|
||||
private ListOperations<String, String> redisListOps;
|
||||
private HashOperations<String, String, String> redisHashOps;
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String redisHost;
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private String redisPort;
|
||||
|
||||
@Value("${spring.redis.database}")
|
||||
private String redisDB;
|
||||
|
||||
@Value("${application.node.id}")
|
||||
private String appNodeId;
|
||||
|
||||
|
||||
/**
|
||||
* 使用StringRedisTemplate而不是RedisTemplate解决序列化问题
|
||||
* https://stackoverflow.com/questions/13215024/weird-redis-key-with-spring-data-jedis
|
||||
*/
|
||||
@Autowired
|
||||
private StringRedisTemplate redis;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
redisListOps = redis.opsForList();
|
||||
redisHashOps = redis.opsForHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish Message into Channel with redis PubSub
|
||||
*
|
||||
* @param j
|
||||
*/
|
||||
public void publish(JsonObject j) {
|
||||
ChannelTopic ct = new ChannelTopic(String.format(Constants.INSTANT_MESSTRING_WEBIM_AGENT_PATTERN, appNodeId));
|
||||
j.addProperty("node", appNodeId);
|
||||
redis.convertAndSend(ct.getTopic(), j.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] bytes) {
|
||||
logger.debug("[instant messaging] onMessage {}", message);
|
||||
String payload = new String(message.getBody());
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject j = parser.parse(payload).getAsJsonObject();
|
||||
logger.debug("[instant messaging] message body {}", j.toString());
|
||||
try {
|
||||
NettyClients.getInstance().sendAgentEventMessage(j.get("id").getAsString(),
|
||||
j.get("event").getAsString(),
|
||||
IMServiceUtils.deserialize(j.get("data").getAsString()));
|
||||
} catch (Exception e) {
|
||||
logger.error("onMessage", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.app.schedule;
|
||||
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.util.IMServiceUtils;
|
||||
import com.chatopera.cc.util.Constants;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.ListOperations;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.*;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 访客消息分发
|
||||
*/
|
||||
@Component
|
||||
public class WebIMOnlineUserDispatcher implements MessageListener {
|
||||
private final static Logger logger = LoggerFactory.getLogger(WebIMOnlineUserDispatcher.class);
|
||||
|
||||
private ListOperations<String, String> redisListOps;
|
||||
private HashOperations<String, String, String> redisHashOps;
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String redisHost;
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private String redisPort;
|
||||
|
||||
@Value("${spring.redis.database}")
|
||||
private String redisDB;
|
||||
|
||||
@Value("${application.node.id}")
|
||||
private String appNodeId;
|
||||
|
||||
|
||||
/**
|
||||
* 使用StringRedisTemplate而不是RedisTemplate解决序列化问题
|
||||
* https://stackoverflow.com/questions/13215024/weird-redis-key-with-spring-data-jedis
|
||||
*/
|
||||
@Autowired
|
||||
private StringRedisTemplate redis;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
redisListOps = redis.opsForList();
|
||||
redisHashOps = redis.opsForHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish Message into Channel with redis PubSub
|
||||
*
|
||||
* @param j
|
||||
*/
|
||||
public void publish(JsonObject j) {
|
||||
ChannelTopic ct = new ChannelTopic(String.format(Constants.INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN, appNodeId));
|
||||
j.addProperty("node", appNodeId);
|
||||
redis.convertAndSend(ct.getTopic(), j.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] bytes) {
|
||||
logger.debug("[instant messaging] onMessage {}", message);
|
||||
String payload = new String(message.getBody());
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject j = parser.parse(payload).getAsJsonObject();
|
||||
logger.debug("[instant messaging] message body {}", j.toString());
|
||||
try {
|
||||
NettyClients.getInstance().sendIMEventMessage(j.get("id").getAsString(),
|
||||
j.get("event").getAsString(),
|
||||
IMServiceUtils.deserialize(j.get("data").getAsString()));
|
||||
} catch (Exception e) {
|
||||
logger.error("onMessage", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,25 +15,19 @@
|
||||
*/
|
||||
package com.chatopera.cc.app.schedule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.basic.MainUtils;
|
||||
import com.chatopera.cc.exchange.DataExchangeInterface;
|
||||
import com.chatopera.cc.util.freeswitch.model.CallCenterAgent;
|
||||
import com.chatopera.cc.app.cache.CacheHelper;
|
||||
import com.chatopera.cc.app.persistence.impl.CallOutQuene;
|
||||
import com.chatopera.cc.app.persistence.repository.AgentUserTaskRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.JobDetailRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.OnlineUserRepository;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.im.client.NettyClients;
|
||||
import com.chatopera.cc.app.im.message.ChatMessage;
|
||||
import com.chatopera.cc.app.im.router.OutMessageRouter;
|
||||
import com.chatopera.cc.app.model.*;
|
||||
import com.chatopera.cc.app.persistence.impl.CallOutQuene;
|
||||
import com.chatopera.cc.app.persistence.repository.*;
|
||||
import com.chatopera.cc.exchange.DataExchangeInterface;
|
||||
import com.chatopera.cc.util.OnlineUserUtils;
|
||||
import com.chatopera.cc.util.freeswitch.model.CallCenterAgent;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -43,18 +37,10 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import com.chatopera.cc.app.persistence.repository.ChatMessageRepository;
|
||||
import com.chatopera.cc.app.persistence.repository.ConsultInviteRepository;
|
||||
import com.chatopera.cc.app.model.AgentStatus;
|
||||
import com.chatopera.cc.app.model.AgentUser;
|
||||
import com.chatopera.cc.app.model.AgentUserTask;
|
||||
import com.chatopera.cc.app.model.AiConfig;
|
||||
import com.chatopera.cc.app.model.AiUser;
|
||||
import com.chatopera.cc.app.model.CousultInvite;
|
||||
import com.chatopera.cc.app.model.JobDetail;
|
||||
import com.chatopera.cc.app.model.MessageOutContent;
|
||||
import com.chatopera.cc.app.model.OnlineUser;
|
||||
import com.chatopera.cc.app.model.SessionConfig;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
@ -72,7 +58,7 @@ public class WebIMTask {
|
||||
@Autowired
|
||||
private TaskExecutor webimTaskExecutor;
|
||||
|
||||
@Scheduled(fixedDelay = 5000) // 每5秒执行一次
|
||||
@Scheduled(fixedDelay = 5000) // 处理超时消息,每5秒执行一次
|
||||
public void task() {
|
||||
List<SessionConfig> sessionConfigList = AutomaticServiceDist.initSessionConfigList();
|
||||
if (sessionConfigList != null && sessionConfigList.size() > 0 && MainContext.getContext() != null) {
|
||||
@ -255,7 +241,7 @@ public class WebIMTask {
|
||||
private void processMessage(SessionConfig sessionConfig, String message, String servicename, AgentUser agentUser, AgentStatus agentStatus, AgentUserTask task) {
|
||||
|
||||
MessageOutContent outMessage = new MessageOutContent();
|
||||
if (!StringUtils.isBlank(message)) {
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
outMessage.setMessage(message);
|
||||
outMessage.setMessageType(MainContext.MediaTypeEnum.TEXT.toString());
|
||||
outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
@ -279,7 +265,7 @@ public class WebIMTask {
|
||||
data.setAgentserviceid(agentUser.getAgentserviceid());
|
||||
|
||||
data.setCalltype(MainContext.CallTypeEnum.OUT.toString());
|
||||
if (!StringUtils.isBlank(agentUser.getAgentno())) {
|
||||
if (StringUtils.isNotBlank(agentUser.getAgentno())) {
|
||||
data.setTouser(agentUser.getUserid());
|
||||
}
|
||||
data.setChannel(agentUser.getChannel());
|
||||
@ -304,11 +290,12 @@ public class WebIMTask {
|
||||
*/
|
||||
MainContext.getContext().getBean(ChatMessageRepository.class).save(data);
|
||||
|
||||
if (agentUser != null && !StringUtils.isBlank(agentUser.getAgentno())) { //同时发送消息给双方
|
||||
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
// 同时发送消息给双方
|
||||
if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) {
|
||||
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(data.getTouser())) {
|
||||
if (StringUtils.isNotBlank(data.getTouser())) {
|
||||
OutMessageRouter router = null;
|
||||
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
|
||||
if (router != null) {
|
||||
|
@ -17,9 +17,12 @@ package com.chatopera.cc.concurrent.chatbot;
|
||||
|
||||
import com.chatopera.cc.concurrent.user.UserDataEvent;
|
||||
import com.lmax.disruptor.RingBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ChatbotEventProducer {
|
||||
private final static Logger logger = LoggerFactory.getLogger(ChatbotEventProducer.class);
|
||||
private final RingBuffer<UserDataEvent> ringBuffer;
|
||||
|
||||
public ChatbotEventProducer(RingBuffer<UserDataEvent> ringBuffer)
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.chatopera.cc.util;
|
||||
|
||||
import com.chatopera.cc.app.basic.MainContext;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -30,6 +31,14 @@ public class Constants {
|
||||
public final static String IM_MESSAGE_TYPE_MESSAGE = "message";
|
||||
public final static String CHATBOT_EVENT_TYPE_CHAT = "chat";
|
||||
|
||||
|
||||
/**
|
||||
* Modules
|
||||
*/
|
||||
public final static String CSKEFU_MODULE_CALLOUT = "sales";
|
||||
public final static String CSKEFU_MODULE_CHATBOT = "chatbot";
|
||||
public final static String CSKEFU_MODULE_CONTACTS = "contacts";
|
||||
|
||||
/**
|
||||
* Formatter
|
||||
*/
|
||||
@ -38,6 +47,21 @@ public class Constants {
|
||||
public final static SimpleDateFormat DISPLAY_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
public final static DecimalFormat DURATION_MINS_FORMATTER = new DecimalFormat("0.00");
|
||||
|
||||
|
||||
/**
|
||||
* Instant Messaging Events
|
||||
*/
|
||||
public final static String INSTANT_MESSTRING_WEBIM_AGENT_PATTERN = "im:webim:agent:%s:events";
|
||||
public final static String INSTANT_MESSAGING_WEBIM_AGENT_CHANNEL = String.format(INSTANT_MESSTRING_WEBIM_AGENT_PATTERN, "*");
|
||||
public final static String INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN = "im:webim:onlineuser:%s:events";
|
||||
public final static String INSTANT_MESSAGING_WEBIM_ONLINE_USER_CHANNEL = String.format(INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN, "*");
|
||||
|
||||
/**
|
||||
* Attachment File Type
|
||||
*/
|
||||
public final static String ATTACHMENT_TYPE_IMAGE = "image";
|
||||
public final static String ATTACHMENT_TYPE_FILE = "file";
|
||||
|
||||
/**
|
||||
* FreeSwitch Communication
|
||||
*/
|
||||
|
@ -908,6 +908,7 @@ public class OnlineUserUtils {
|
||||
if (!StringUtils.isBlank(ip)) {
|
||||
ipdata = IPTools.getInstance().findGeography(ip);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(nickname)) {
|
||||
nickname = "Guest_" + userid;
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class StreamingFileUtils {
|
||||
|
||||
private static StreamingFileUtils singleton = new StreamingFileUtils();
|
||||
|
||||
private final HashMap<String, String> extMap = new HashMap<String, String>();
|
||||
|
||||
private StreamingFileUtils() {
|
||||
extMap.put(Constants.ATTACHMENT_TYPE_IMAGE, "gif,jpg,jpeg,png,bmp");
|
||||
extMap.put(Constants.ATTACHMENT_TYPE_FILE, "pdf,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,c66");
|
||||
extMap.put("flash", "swf,flv");
|
||||
extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
|
||||
}
|
||||
|
||||
public static StreamingFileUtils getInstance() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate file format
|
||||
* @param type
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
public String validate(final String type, final String filename) {
|
||||
final String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
|
||||
if (!Arrays.<String>asList(extMap.get(type).split(",")).contains(ext)) {
|
||||
return "上传文件扩展名是不允许的扩展名。只允许" + extMap.get(type) + "格式。";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.util;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public class SystemEnvHelper {
|
||||
|
||||
/**
|
||||
* 分析是否加载模块,在变量为不存在或变量值为true的情况下加载
|
||||
* 也就是说,该变量值不为空或为true时时加载
|
||||
* @param environmentVariable
|
||||
* @return
|
||||
*/
|
||||
public static boolean parseModuleFlag(final String environmentVariable){
|
||||
String val = System.getenv(environmentVariable);
|
||||
return StringUtils.isBlank(val) || StringUtils.equalsIgnoreCase(val, "true");
|
||||
}
|
||||
}
|
@ -15,10 +15,11 @@
|
||||
# https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/htmlsingle/
|
||||
# https://stackoverflow.com/questions/35531661/using-env-variable-in-spring-boots-application-properties
|
||||
|
||||
|
||||
# 证书相关信息
|
||||
license.client.id=bxzq
|
||||
application.version=1.0.0
|
||||
license.client.id=cskefu
|
||||
application.version=3.9.0
|
||||
# 在集群状态下,每个Node都有自己唯一的ID
|
||||
application.node.id=localhost
|
||||
|
||||
# security
|
||||
management.security.enabled=false
|
||||
@ -30,11 +31,6 @@ server.log.path=../logs
|
||||
server.log.level=INFO
|
||||
web.upload-path=../data
|
||||
|
||||
# multi part
|
||||
spring.servlet.multipart.enabled=true
|
||||
spring.servlet.multipart.max-file-size=20MB
|
||||
spring.servlet.multipart.max-request-size=50MB
|
||||
|
||||
# IM Server
|
||||
uk.im.server.port=8036
|
||||
uk.im.server.host=localhost
|
||||
@ -132,7 +128,7 @@ spring.redis.port=6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
spring.redis.pool.max-active=20
|
||||
spring.redis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
spring.redis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
@ -153,3 +149,11 @@ cskefu.callout.watch.interval=60000
|
||||
storage.minio.url=http://192.168.2.217:9000
|
||||
storage.minio.access_key=M19Q8YJ8FzLyQtST7r0
|
||||
storage.minio.secret_key=KHv6qjddHD4HfR1m7fjY7HglSO1WOSzIeTERRUUc
|
||||
|
||||
# multi part
|
||||
spring.servlet.multipart.enabled=true
|
||||
spring.servlet.multipart.max-file-size=15MB
|
||||
spring.servlet.multipart.max-request-size=15MB
|
||||
|
||||
# MySQL Blob
|
||||
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
|
||||
|
@ -24,7 +24,7 @@
|
||||
xmlns="http://www.hazelcast.com/schema/config"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<group>
|
||||
<name>CSKeFu_U0C</name>
|
||||
<name>CSKeFu_IMDG</name>
|
||||
<password>CSKeFu-1234567890</password>
|
||||
</group>
|
||||
<network>
|
||||
|
50
contact-center/app/src/main/resources/static/testclient.html
Normal file
50
contact-center/app/src/main/resources/static/testclient.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<!-- 本页只用于测试/演示目的 -->
|
||||
|
||||
<head>
|
||||
<!-- META -->
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>春松客服</title>
|
||||
<!-- 春松客服访客端演示程序 https://github.com/chatopera/cosin/wiki/春松客服访客端演示 -->
|
||||
<!-- 系统:客服接入:网站列表:创建新网站 网站地址(localhost) -->
|
||||
<script defer="true" src="/im/104eac.html"></script>
|
||||
<style>
|
||||
tr.top td { border-top: thin solid black; }
|
||||
tr.bottom td { border-bottom: thin solid black; }
|
||||
tr.row td:first-child { border-left: thin solid black; }
|
||||
tr.row td:last-child { border-right: thin solid black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>春松客服演示客户端</h2>
|
||||
|
||||
<h3>设置网站渠道</h3>
|
||||
以管理员身份 <a href="/" target="_blank">登录</a>,导航【系统-客服接入-网站列表-创建新网站】,按照如下内容设置网站渠道。
|
||||
|
||||
<table style="width:100%">
|
||||
<tr class="top bottom row">
|
||||
<th>设置</th>
|
||||
<th>值</th>
|
||||
<th>描述</th>
|
||||
</tr>
|
||||
<tr class="top bottom row">
|
||||
<td>网站名称</td>
|
||||
<td>localhost</td>
|
||||
<td>任意字符串</td>
|
||||
</tr>
|
||||
<tr class="top bottom row">
|
||||
<td>网站地址</td>
|
||||
<td>localhost</td>
|
||||
<td>网站的域名或IP,端口选填,比如 localhost:8080</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
然后,刷新本页面,就可以在右下角看到【在线客服】聊天控件,通过<a href="https://github.com/chatopera/cosin/wiki/%E6%98%A5%E6%9D%BE%E5%AE%A2%E6%9C%8D%E8%AE%BF%E5%AE%A2%E7%AB%AF%E6%BC%94%E7%A4%BA" target="_blank">详细文档</a>进一步了解在任意网站集成客服控件的方法。
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -32,7 +32,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">欢迎提示语:</label>
|
||||
<div class="layui-input-inline">
|
||||
<textarea id="welcomemsg" style="width:450px;" name="welcomemsg" class="layui-textarea">${extention.welcomemsg!"您好,欢迎致电优客服智能IVR演示系统,这里是电话机器人演示系统,请说要进入的测试流程,比如,客服系统!"}</textarea>
|
||||
<textarea id="welcomemsg" style="width:450px;" name="welcomemsg" class="layui-textarea">${extention.welcomemsg!"您好,欢迎致电春松客服智能IVR演示系统,这里是电话机器人演示系统,请说要进入的测试流程,比如,客服系统!"}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -32,17 +32,15 @@
|
||||
<#list snsAccountList.content as snsAccount>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/admin/callout/index.html?snsid=${snsAccount.snsid!''}">
|
||||
${snsAccount.name!''}
|
||||
</a>
|
||||
</td>
|
||||
<td>${snsAccount.baseURL!''}</td>
|
||||
<td>${snsAccount.createtime?string("yyyy-MM-dd HH:mm:ss")}</td>
|
||||
<td style="white-space:nowrap;" nowrap="nowrap">
|
||||
<a href="/admin/callout/edit.html?id=${snsAccount.id!''}" data-toggle="ajax" data-width="550" data-height="300" data-title="编辑">
|
||||
<i class="layui-icon"></i>
|
||||
编辑
|
||||
</a>
|
||||
<!--<a href="/admin/callout/edit.html?id=${snsAccount.id!''}" data-toggle="ajax" data-width="550" data-height="300" data-title="编辑">-->
|
||||
<!--<i class="layui-icon"></i>-->
|
||||
<!--编辑-->
|
||||
<!--</a>-->
|
||||
<#if !(snsAccount.usertype?? && snsAccount.usertype == "0") && snsAccount.datastatus != true >
|
||||
<a href="/admin/callout/delete.html?id=${snsAccount.id!''}" style="margin-left:10px;" data-toggle="tip" <#if secret?? && secret.enable == true>data-confirm="请输入二次安全验证密码"</#if> title="删除语音需要进行二次密码验证,请确认是否删除?" >
|
||||
<i class="layui-icon" style="color:red;">ဆ</i>
|
||||
|
@ -33,14 +33,16 @@
|
||||
<#list snsAccountList.content as snsAccount>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/admin/webim/index.html?snsid=${snsAccount.snsid!''}">
|
||||
${snsAccount.name!''}
|
||||
</a>
|
||||
</td>
|
||||
<td>${snsAccount.baseURL!''}</td>
|
||||
<td>${snsAccount.snsid!''}</td>
|
||||
<td>${snsAccount.createtime?string("yyyy-MM-dd HH:mm:ss")}</td>
|
||||
<td style="white-space:nowrap;" nowrap="nowrap">
|
||||
<a href="/admin/webim/index.html?snsid=${snsAccount.snsid!''}">
|
||||
<i class="layui-icon"></i>
|
||||
接入
|
||||
</a>
|
||||
<a href="/admin/im/edit.html?id=${snsAccount.id!''}" data-toggle="ajax" data-width="550" data-height="300" data-title="编辑网站">
|
||||
<i class="layui-icon"></i>
|
||||
编辑
|
||||
|
@ -11,11 +11,11 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">1、系统颜色风格选择</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">系统颜色风格选择</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<p>优客服系统界面颜色风格</p>
|
||||
<p>春松客服系统界面颜色风格</p>
|
||||
<p style="color:#888888;font-size:13px;margin-top:10px;">默认的配色是绿色,选择颜色可以在右侧预览风格,点击保存即可生效</p>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
@ -29,8 +29,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">2、请填写服务器的访问地址</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">请填写服务器的访问地址</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -39,7 +39,7 @@
|
||||
</div>
|
||||
<div class="col-lg-4" style="text-align:right;">
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="iconstr" value="<#if systemConfig.iconstr?? && systemConfig.iconstr!= ''>${systemConfig.iconstr!''}<#else>www.chatopera.com</#if>" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="iconstr" value="<#if systemConfig.iconstr?? && systemConfig.iconstr!= ''>${systemConfig.iconstr!''}</#if>" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">3、产品登录界面和后台管理界面标题</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">产品登录界面和后台管理界面标题</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -62,7 +62,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">4、登录页欢迎Logo图片</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">登录页欢迎Logo图片</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -87,7 +87,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">5、产品后台管理界面Logo图片</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">产品后台管理界面Logo图片</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -112,7 +112,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">6、产品标题栏缩略小图</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">产品标题栏缩略小图</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -137,7 +137,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">7、重启或停止对话服务</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">重启或停止对话服务</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -153,8 +153,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">8、启用EntIM内部IM功能</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用EntIM内部IM功能</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -165,7 +165,8 @@
|
||||
<#if entim?? && entim == true>
|
||||
<a href="/admin/config/stopentim.html" data-toggle="tip" title="请确认是否关闭EntIM功能?" class="layui-btn layui-btn-small layui-btn-danger">关闭EntIM功能</a>
|
||||
<#else>
|
||||
<a href="/admin/config/startentim.html" data-toggle="tip" title="启用EntIM功能" class="layui-btn layui-btn-small">启用EntIM功能</a>
|
||||
<!-- <a href="/admin/config/startentim.html" data-toggle="tip" title="启用EntIM功能" class="layui-btn layui-btn-small">启用EntIM功能</a> -->
|
||||
<a href="" data-toggle="tip" title="启用EntIM功能" class="layui-btn layui-btn-small">启用EntIM功能</a>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
@ -173,12 +174,12 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">9、启用权限数据采集功能功能</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用权限数据采集功能功能</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<p>启用权限数据采集功能后,会进入数据采集模式,当前状态:<#if infoace?? && infoace == true><small class="ukefu-label theme4">已启用</small><#else><small class="ukefu-label theme4" style="background-color:#FF5722;">已关闭</small></#if></p>
|
||||
<p style="color:#888888;font-size:13px;margin-top:10px;">启用后,在优客服界面上的任何链接点击操作都会触发数据收集功能</p>
|
||||
<p style="color:#888888;font-size:13px;margin-top:10px;">启用后,在春松客服界面上的任何链接点击操作都会触发数据收集功能</p>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<#if infoace?? && infoace == true>
|
||||
@ -191,8 +192,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">10、停止优客服系统</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">停止春松客服系统</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -207,7 +208,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">11、修改微信接收消息的日志级别</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">修改微信接收消息的日志级别</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -223,8 +224,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">12、启用服务SSL安全访问</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用服务SSL安全访问</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -265,8 +266,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">13、启用涉及重要操作的二次验证密码</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用涉及重要操作的二次验证密码</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -309,7 +310,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">14、百度地图的Key代码(AK)</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">百度地图的Key代码(AK)</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -323,8 +324,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">15、工单系统布局方式</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">工单系统布局方式</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -339,7 +340,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">16、启用权限控制</div>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用权限控制</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -353,8 +354,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">17、启用语音平台模板配置</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用语音平台模板配置</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -492,8 +493,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">18、启用工单系统的邮件通知</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用工单系统的邮件通知</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
@ -627,8 +628,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ukefu-webim-prop">
|
||||
<div class="ukefu-webim-tl" style="clear:both;">19、启用多${systemConfig.namealias!'租户'}管理模式</div>
|
||||
<div class="ukefu-webim-prop" hidden>
|
||||
<div class="ukefu-webim-tl" style="clear:both;">启用多${systemConfig.namealias!'租户'}管理模式</div>
|
||||
<div class="box-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
|
@ -24,9 +24,11 @@
|
||||
<dd <#if subtype?? && (maintype == 'webim' || subtype == 'im')>class="layui-this"</#if>>
|
||||
<a href="/admin/im/index.html">网站列表</a>
|
||||
</dd>
|
||||
<#if models?? && models["sales"]?? && models["sales"] == true>
|
||||
<dd <#if subtype?? && (maintype == 'callout' || subtype == 'channel')>class="layui-this"</#if>>
|
||||
<a href="/admin/callout/index.html">语音渠道</a>
|
||||
</dd>
|
||||
</#if>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
</span>
|
||||
</h1>
|
||||
<div class="row" style="padding:5px;">
|
||||
<p style="color:red">提示:除管理员外,账号必须在【组织结构】中关联一个部门,必须在【系统角色】中关联一个角色,才可以使用资源。设置后,该账号需重新登系统才能生效。</p>
|
||||
<div class="col-lg-12">
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<colgroup>
|
||||
|
@ -30,6 +30,11 @@
|
||||
<#if inviteData??>
|
||||
<input type="hidden" name="id" value="${inviteData.id!''}">
|
||||
<input type="hidden" name="snsaccountid" value="${inviteData.snsaccountid!''}">
|
||||
<input type="hidden" name="ai" value="${inviteData.ai!''}">
|
||||
<input type="hidden" name="aisuccesstip" value="${inviteData.aisuccesstip!''}">
|
||||
<input type="hidden" name="aifirst" value="${inviteData.aifirst!''}">
|
||||
<input type="hidden" name="ainame" value="${inviteData.ainame!''}">
|
||||
<input type="hidden" name="aiid" value="${inviteData.aiid!''}">
|
||||
</#if>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
@ -30,6 +30,11 @@
|
||||
<#if inviteData??>
|
||||
<input type="hidden" name="id" value="${inviteData.id!''}">
|
||||
<input type="hidden" name="snsaccountid" value="${inviteData.snsaccountid!''}">
|
||||
<input type="hidden" name="ai" value="${inviteData.ai!''}">
|
||||
<input type="hidden" name="aisuccesstip" value="${inviteData.aisuccesstip!''}">
|
||||
<input type="hidden" name="aifirst" value="${inviteData.aifirst!''}">
|
||||
<input type="hidden" name="ainame" value="${inviteData.ainame!''}">
|
||||
<input type="hidden" name="aiid" value="${inviteData.aiid!''}">
|
||||
</#if>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
@ -30,6 +30,11 @@
|
||||
<#if inviteData??>
|
||||
<input type="hidden" name="id" value="${inviteData.id!''}">
|
||||
<input type="hidden" name="snsaccountid" value="${inviteData.snsaccountid!''}">
|
||||
<input type="hidden" name="ai" value="${inviteData.ai!''}">
|
||||
<input type="hidden" name="aisuccesstip" value="${inviteData.aisuccesstip!''}">
|
||||
<input type="hidden" name="aifirst" value="${inviteData.aifirst!''}">
|
||||
<input type="hidden" name="ainame" value="${inviteData.ainame!''}">
|
||||
<input type="hidden" name="aiid" value="${inviteData.aiid!''}">
|
||||
</#if>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
@ -50,7 +55,7 @@
|
||||
<p style="color:#888888;font-size:13px;margin-top:10px;">默认显示信息 企业名称</p>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="dialog_name" value="${inviteData.dialog_name!'优客服'}" autocomplete="off" class="layui-input" oninput="$('#dialog_name').text($(this).val())" onchange="$('#dialog_name').text($(this).val())">
|
||||
<input type="text" name="dialog_name" value="${inviteData.dialog_name!'春松客服'}" autocomplete="off" class="layui-input" oninput="$('#dialog_name').text($(this).val())" onchange="$('#dialog_name').text($(this).val())">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -205,7 +210,7 @@
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="consult_skill_title" value="${inviteData.consult_skill_title!'优客服'}" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="consult_skill_title" value="${inviteData.consult_skill_title!'春松客服'}" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -472,7 +477,7 @@
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="aisuccesstip" maxlength="100" value="${inviteData.aisuccesstip!'欢迎使用优客服小E,我来帮您解答问题'}" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="aisuccesstip" maxlength="100" value="${inviteData.aisuccesstip!'欢迎使用春松客服小E,我来帮您解答问题'}" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -584,16 +589,16 @@
|
||||
<div class="ukefu-im-profile" style="width:130px;font-size:12px;">
|
||||
<div class="ukefu-profile-title" style="clear:both;">信息提示</div>
|
||||
<div class="box-item" style="padding:5px;white-space: nowrap;text-overflow: ellipsis;">
|
||||
名称:<label id="dialog_name">${inviteData.dialog_name!'优客服'}</label>
|
||||
名称:<label id="dialog_name">${inviteData.dialog_name!'春松客服'}</label>
|
||||
</div>
|
||||
<div class="box-item" style="padding:5px;white-space: nowrap;text-overflow: ellipsis;">
|
||||
地址:<label id="dialog_address">${inviteData.dialog_address!'广东深圳'}</label>
|
||||
地址:<label id="dialog_address">${inviteData.dialog_address!'北京'}</label>
|
||||
</div>
|
||||
<div class="box-item" style="padding:5px;white-space: nowrap;text-overflow: ellipsis;">
|
||||
电话:<label id="dialog_phone">${inviteData.dialog_phone!'0755-xxxxxxxx'}</label>
|
||||
电话:<label id="dialog_phone">${inviteData.dialog_phone!'185-1935-7507'}</label>
|
||||
</div>
|
||||
<div class="box-item" style="padding:5px;white-space: nowrap;text-overflow: ellipsis;">
|
||||
邮件:<label id="dialog_mail">${inviteData.dialog_mail!'kefu@ukewo.cn'}</label>
|
||||
邮件:<label id="dialog_mail">${inviteData.dialog_mail!'info@chatopera.com'}</label>
|
||||
</div>
|
||||
<div class="box-item" style="padding:5px;text-indent: 25px;line-height:25px;">
|
||||
<label id="dialog_introduction">${inviteData.dialog_introduction!'客服公告信息,内容在控制台设置。'}</label>
|
||||
|
@ -2,14 +2,16 @@
|
||||
<li class="ukefu-channel-tip">
|
||||
访问渠道:<i class="layui-icon"></i>
|
||||
在线客服
|
||||
<#if summary??>
|
||||
<div class="ukefu-summary">
|
||||
<a href="/agent/summary.html?userid=${curagentuser.userid!''}&agentserviceid=${curagentuser.agentserviceid!''}&agentuserid=${curagentuser.id}" data-toggle="ajax" data-width="950" data-height="450" title="记录服务小结">
|
||||
<i class="layui-icon"></i> 已记录服务小结
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ukefu-channel-tip">
|
||||
服务小结: <#if summary??>
|
||||
<i class="layui-icon"></i>已记录
|
||||
<#else>
|
||||
<i class="layui-icon"></i>未记录
|
||||
</#if>
|
||||
</li>
|
||||
|
||||
<#if snsAccount??>
|
||||
<li class="ukefu-channel-tip">
|
||||
接入网站:${snsAccount.name!''}(${snsAccount.baseURL!''})
|
||||
|
@ -5,14 +5,16 @@
|
||||
<li class="ukefu-channel-tip">
|
||||
访问渠道:<i class="kfont"></i>
|
||||
微信
|
||||
<#if summary??>
|
||||
<div class="ukefu-summary">
|
||||
<a href="/agent/summary.html?userid=${curagentuser.userid!''}&agentserviceid=${curagentuser.agentserviceid!''}&agentuserid=${curagentuser.id}" data-toggle="ajax" data-width="950" data-height="450" title="记录服务小结">
|
||||
<i class="layui-icon"></i> 已记录服务小结
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ukefu-channel-tip">
|
||||
服务小结: <#if summary??>
|
||||
<i class="layui-icon"></i>已记录
|
||||
<#else>
|
||||
<i class="layui-icon"></i>未记录
|
||||
</#if>
|
||||
</li>
|
||||
|
||||
<#if snsAccount??>
|
||||
<li class="ukefu-channel-tip">
|
||||
公众号:${snsAccount.name}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<#if contacts.gender?? && contacts.gender == '-1'>未知</#if>
|
||||
</li>
|
||||
<li>
|
||||
生日:${contacts.birthday!''}
|
||||
生日:${contacts.cusbirthday!''}
|
||||
</li>
|
||||
<li>
|
||||
电话:<span class="ukefu-phone-number">${contacts.phone!''}</span>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<h1 class="site-h1">
|
||||
<#if curagentuser??>${curagentuser.username!''}(${curagentuser.region!''})
|
||||
<div style="float:right;" class="ukefu-service-btn">
|
||||
<a href="/agent/summary.html?userid=${curagentuser.userid!''}&agentserviceid=${curagentuser.agentserviceid!''}&agentuserid=${curagentuser.id}" data-toggle="ajax" data-width="950" data-height="450" title="记录服务小结"><button class="layui-btn layui-btn-small"><i class="kfont"></i> 服务小结</button></a>
|
||||
<a href="/agent/summary.html?userid=${curagentuser.userid!''}&agentserviceid=${curagentuser.agentserviceid!''}&agentuserid=${curagentuser.id}&channel=${curagentuser.channel}" data-toggle="ajax" data-width="950" data-height="450" title="记录服务小结"><button class="layui-btn layui-btn-small"><i class="kfont"></i> 服务小结</button></a>
|
||||
<a href="/agent/transfer.html?userid=${curagentuser.userid!''}&agentserviceid=${curagentuser.agentserviceid!''}&agentuserid=${curagentuser.id}" data-toggle="ajax" data-width="950" data-height="550" title="选择转接对象"><button class="layui-btn layui-btn-small"><i class="kfont"></i> 转接坐席</button></a>
|
||||
<a href="/agent/end.html?userid=${curagentuser.id!''}" data-toggle="tip" data-title="请确认是否关闭和用户“${curagentuser.username!''}”的对话?"><button class="layui-btn layui-btn-small layui-btn-danger"><i class="kfont"></i> 结束对话</button></a>
|
||||
</div>
|
||||
|
@ -35,7 +35,7 @@
|
||||
//创建新的图片对象
|
||||
var img = new Image();
|
||||
//指定图片的URL
|
||||
img.src = "/res/image.html?id=upload/${chatMessage.attachmentid!''}_cooperation";
|
||||
img.src = "/res/image.html?id=${chatMessage.attachmentid!''}&cooperation=true&original=true";
|
||||
//浏览器加载图片完毕后再绘制图片
|
||||
img.onload = function(){
|
||||
//以Canvas画布上的坐标(10,10)为起始点,绘制图像
|
||||
@ -49,7 +49,7 @@
|
||||
<div class='ukefu-preview-image scrawl-main' id="scrawl-main">
|
||||
<div class='ukefu-image-content hot'>
|
||||
<div class='ukefu-image-canvas' id='ukefu-image-content'>
|
||||
<img id="ukefu_img_ctx" src='${chatMessage.message!''}_original'>
|
||||
<img id="ukefu_img_ctx" src='${chatMessage.message!''}&original=true'>
|
||||
</div>
|
||||
<div class='drawBoard'>
|
||||
<canvas id="canvas-borad" class="brushBorad">你的浏览器不支持 canvas 绘图</canvas>
|
||||
|
@ -5,6 +5,7 @@
|
||||
<input type="hidden" name="userid" value="${userid!''}">
|
||||
<input type="hidden" name="agentserviceid" value="${agentserviceid!''}">
|
||||
<input type="hidden" name="agentuserid" value="${agentuserid!''}">
|
||||
<input type="hidden" name="channel" value="${channel!''}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
|
@ -43,9 +43,9 @@
|
||||
<label class="layui-form-label">笔记分类:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select id="notesCategory" name="notesCategory" lay-filter="category" required lay-verify="required" style="display: inline">
|
||||
<option value="webim">网页</option>
|
||||
<option value="callout">外呼</option>
|
||||
<option value="callin">呼入</option>
|
||||
<option value="webim">网页</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -143,7 +143,7 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">生日:</label>
|
||||
<div class="layui-input-inline" style="line-height: 2.5em;">
|
||||
${contacts.birthday!''}
|
||||
${contacts.cusbirthday!''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -178,7 +178,7 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">生日:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="birthday" name="contacts.birthday" autocomplete="off"
|
||||
<input type="text" id="birthday" name="contacts.cusbirthday" autocomplete="off"
|
||||
class="layui-input">
|
||||
<i class="layui-icon" style="position: absolute;right: 3px;top: 6px;font-size: 25px;"></i>
|
||||
</div>
|
||||
|
@ -193,7 +193,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -233,7 +233,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -273,7 +273,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -311,7 +311,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -94,7 +94,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -134,7 +134,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -174,7 +174,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -212,7 +212,7 @@
|
||||
[知识概况] 45 浏览 , 15收藏 , 5评论 , 2017-10-02 15:40:33前有效
|
||||
<span>
|
||||
<i class="kfont"></i>
|
||||
<a href="">优客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
<a href="">春松客服v3.1.0 产品说明书.pdf 等3个附件</a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -30,9 +30,10 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">智能问答引擎地址</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="baseUrl" required lay-verify="required" placeholder="请输入智能问答引擎地址"
|
||||
<input type="text" name="baseUrl" required lay-verify="required" placeholder="联系info@chatopera.com,获得智能问答引擎地址"
|
||||
autocomplete="off" class="layui-input" value="${bot.baseUrl}" <#if id!=null>disabled</#if>>
|
||||
</div>
|
||||
<label class="layui-form-label"></label>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">名称</label>
|
||||
@ -50,6 +51,13 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">问候语</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="welcome" required lay-verify="required" placeholder="请输入问候语" autocomplete="off"
|
||||
class="layui-input" value="${bot.welcome}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">兜底回复</label>
|
||||
<div class="layui-input-inline">
|
||||
@ -115,7 +123,7 @@
|
||||
if (data.rc == 0) {
|
||||
cb(null, data.data);
|
||||
} else {
|
||||
cb(data.error);
|
||||
cb(data);
|
||||
}
|
||||
})
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
@ -128,10 +136,17 @@
|
||||
var form = layui.form();
|
||||
form.on('submit(save)', function (data) {
|
||||
var field = data.field;
|
||||
|
||||
var submitFinish = function (err, bot) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
layer.confirm(err.data||err.error, {
|
||||
btn: ['关闭'],
|
||||
icon: 2,
|
||||
title: '提示'
|
||||
}, function (popup, layero) {
|
||||
layer.close(popup)
|
||||
}, function (popup) {
|
||||
// 取消方法
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title: '提示'
|
||||
|
@ -68,7 +68,7 @@
|
||||
if (data.rc == 0) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
reject(data.error);
|
||||
reject(data);
|
||||
}
|
||||
})
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
@ -107,7 +107,18 @@
|
||||
|
||||
var isEnabled = $('<td><input type="checkbox" lay-skin="switch" lay-text="开启|关闭" ' + (r.enabled ? 'checked' : '') + '></td>');
|
||||
isEnabled.change(function () {
|
||||
change(r.id, $(this).find('input').prop('checked'));
|
||||
change(r.id, $(this).find('input').prop('checked'))
|
||||
.then(null, function(err){
|
||||
layer.confirm(err.data||err.error, {
|
||||
btn: ['关闭'],
|
||||
icon: 2,
|
||||
title: '提示'
|
||||
}, function (index, layero) {
|
||||
layer.close(index)
|
||||
}, function (index) {
|
||||
// 取消方法
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
var rows = [
|
||||
@ -123,6 +134,16 @@
|
||||
})
|
||||
|
||||
$('#bots').html(tds);
|
||||
}, function(err){
|
||||
layer.confirm(err.data||err.error, {
|
||||
btn: ['关闭'],
|
||||
icon: 2,
|
||||
title: '提示'
|
||||
}, function (popup, layero) {
|
||||
layer.close(popup)
|
||||
}, function (popup) {
|
||||
// 取消方法
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@ -146,7 +167,7 @@
|
||||
}
|
||||
|
||||
function init() {
|
||||
query(1, 10);
|
||||
query(1, 50);
|
||||
}
|
||||
|
||||
layui.use(['form'], function () {
|
||||
|
@ -77,10 +77,10 @@
|
||||
</div>
|
||||
<div class="content-bottom">
|
||||
<span id="welcome-message">
|
||||
<p>欢迎使用优客服企业IM</p>
|
||||
<p>QQ群:<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=637134af30a27220211c843d801ada14700aca69ee8f4acf13f795fe38ea7b94"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="优客服开源项目" title="优客服开源项目"></a></p>
|
||||
<p>优客服企业IM为收费产品</p>
|
||||
<p>详情请咨询:<a href="http://www.ukewo.cn" target="_blank" style="color:#32c24d;">优客服</a></p>
|
||||
<p>欢迎使用春松客服企业IM</p>
|
||||
<p>QQ群:<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=ef3061d99653e2f43619ddcefbf76ac2399196d89fd589501e19ae64423a5a31"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="春松客服开源社区" title="春松客服开源社区"></a></p>
|
||||
<p>春松客服企业IM为收费产品</p>
|
||||
<p>详情请咨询:<a href="https://www.chatopera.com" target="_blank" style="color:#32c24d;">春松客服</a></p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -172,7 +172,7 @@
|
||||
title: '关于' ,
|
||||
btn: '关闭' ,
|
||||
shade: 0 ,
|
||||
content : '<span id="welcome-message"><p>欢迎使用优客服企业IM</p><p>QQ群:<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=637134af30a27220211c843d801ada14700aca69ee8f4acf13f795fe38ea7b94"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="优客服开源项目" title="优客服开源项目"></a></p><p>优客服企业IM为收费产品</p><p>详情请咨询:<a href="http://www.ukewo.cn" target="_blank" style="color:#32c24d;">优客服</a></p></span>'});
|
||||
content : '<span id="welcome-message"><p>欢迎使用春松客服企业IM</p><p>QQ群:<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=ef3061d99653e2f43619ddcefbf76ac2399196d89fd589501e19ae64423a5a31"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="春松客服开源社区" title="春松客服开源社区"></a></p><p>春松客服企业IM为收费产品</p><p>详情请咨询:<a href="https://www.chatopera.com" target="_blank" style="color:#32c24d;">春松客服</a></p></span>'});
|
||||
}
|
||||
function search(){
|
||||
layer.open({
|
||||
|
@ -37,7 +37,7 @@
|
||||
allowInsertUpload:false, //增加的参数,上传图片后是否插入到当前区域
|
||||
allowImageRemote:false,
|
||||
filterMode:true,
|
||||
items: ['emoticons', 'cut' , 'image','insertfile'],
|
||||
items: ['emoticons', 'cut'],
|
||||
htmlTags: {img : ['src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'] , br:[]} ,
|
||||
afterChange : function() {
|
||||
var count = this.count() ;
|
||||
@ -269,9 +269,9 @@
|
||||
<#if !exchange?? || exchange == "true">
|
||||
<li><a href="/im/index.html?appid=${appid!''}&orgi=${orgi!''}&ai=false<#if client??>&client=${client!''}</#if><#if type??>&type=text</#if><#if skill??>&skill=${skill!''}</#if><#if agent??>&agent=${agent!''}</#if><#if title??>&title=${title?url}</#if><#if url??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if>&userid=${userid!''}&sessionid=${sessionid!''}&t=${.now?long}">人工坐席</a></li>
|
||||
</#if>
|
||||
<li class="cur"><a href="javascript:void(0)">智能坐席</a></li>
|
||||
<li class="cur"><a href="javascript:void(0)">智能客服</a></li>
|
||||
<#else>
|
||||
<li class="cur"><a href="javascript:void(0)">智能坐席</a></li>
|
||||
<li class="cur"><a href="javascript:void(0)">智能客服</a></li>
|
||||
</#if>
|
||||
</ul>
|
||||
</div>
|
||||
@ -312,7 +312,7 @@
|
||||
<div class="chat-left">
|
||||
<img class="user-img" src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>" alt="">
|
||||
<div class="chat-message">
|
||||
<label class="user"><#if chatMessage?? && chatMessage.chatype?? && chatMessage.chatype == 'aireply'>${inviteData.ainame!'小E'}<#else>${chatMessage.username!''}</#if></label>
|
||||
<label class="user"><#if chatMessage?? && chatMessage.chatype?? && chatMessage.chatype == 'aireply'>${inviteData.ainame!'小松'}<#else>${chatMessage.username!''}</#if></label>
|
||||
<label class="time">${chatMessage.createtime!''}</label>
|
||||
</div>
|
||||
<div class="chatting-left">
|
||||
@ -453,7 +453,7 @@
|
||||
// 参数连接
|
||||
var hostname = location.hostname ;
|
||||
var protocol = window.location.protocol.replace(/:/g,'');
|
||||
var socket = io.connect(protocol + '://'+hostname+':${port}/im/chatbot?userid=${userid!''}&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if username??>&nickname=${username}</#if><#if agent??>&agent=${agent}</#if><#if title??>&title=${title?url}</#if><#if traceid??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if><#if aiid??>&aiid=${aiid}</#if>');
|
||||
var socket = io(protocol + '://'+hostname+':${port}/im/chatbot?userid=${userid!''}&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if username??>&nickname=${username}</#if><#if agent??>&agent=${agent}</#if><#if title??>&title=${title?url}</#if><#if traceid??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if><#if aiid??>&aiid=${aiid}</#if>', {transports: ['websocket', 'polling']});
|
||||
socket.on('connect',function(){
|
||||
<#if contacts?? && contacts.name??>
|
||||
socket.emit('new', {
|
||||
@ -489,16 +489,15 @@
|
||||
}
|
||||
})
|
||||
socket.on('message', function(data) {
|
||||
console.log("[chatbot io] message ", data);
|
||||
var chat=document.getElementsByClassName('chatting-left').innerText;
|
||||
chat = data.message;
|
||||
if(data.messageType == "image"){
|
||||
chat = "<a href='"+data.message+"_original' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
chat = "<a href='"+data.message+"&original=true' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
}else if(data.messageType == "file"){
|
||||
chat = "<div class='ukefu-message-file'><div class='ukefu-file-icon'><img src='/im/img/file.png'></div><div class='ukefu-file-desc'><a href='"+data.message+"' target='_blank'><div>"+data.filename+"</div><div>"+(data.filesize/1024).toFixed(3)+"Kb</div></a></div></div>" ;
|
||||
}
|
||||
if(data.calltype == "呼入"){
|
||||
output('<div class="chat-right"> <img class="user-img" src="/im/img/user.png" alt=""><div class="chat-message"><label class="time">'+data.createtime+'</label> </div><div class="chatting-right"><i class="arrow arrow${inviteData.consult_dialog_color!''}"></i><div class="chat-content theme${inviteData.consult_dialog_color!''}">'+chat+'</div></div>' , "chat-block");
|
||||
output('<div class="chat-right"> <img class="user-img" src="/im/img/user.png" alt=""><div class="chat-message"><label class="time">'+data.createtime+'</label><label class="user">' + data.username + '</label></div><div class="chatting-right"><i class="arrow arrow${inviteData.consult_dialog_color!''}"></i><div class="chat-content theme${inviteData.consult_dialog_color!''}">'+chat+'</div></div>' , "chat-block");
|
||||
}else if(data.calltype == "呼出"){
|
||||
output('<div class="chat-left"> <img class="user-img" src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>" alt=""><div class="chat-message"><label class="user">'+data.username+'</label><label class="time">'+data.createtime+'</label> </div><div class="chatting-left"><i class="arrow"></i><div class="chat-content">'+chat+'</div></div>' , "chat-block");
|
||||
R3Ajax.audioplayer('audioplane', newmessage, false); // 播放
|
||||
|
@ -174,11 +174,13 @@
|
||||
|
||||
<div class="ukefu-func-tab">
|
||||
<ul>
|
||||
<#if models?? && models["chatbot"]?? && models["chatbot"] == true && inviteData.ai?? && inviteData.ai == true && aiid??>
|
||||
<li><a href="/im/index.html?appid=${appid!''}&orgi=${orgi!''}<#if aiid??>&aiid=${aiid}</#if>&ai=true<#if client??>&client=${client!''}</#if><#if type??>&type=text</#if><#if skill??>&skill=${skill!''}</#if><#if agent??>&agent=${agent!''}</#if>&userid=${userid!''}&sessionid=${sessionid!''}&t=${.now?long}">智能客服</a></li>
|
||||
<li class="cur"><a href="javascript:void(0)">人工坐席</a></li>
|
||||
<#if models?? && models["chatbot"]?? && models["chatbot"] == true && inviteData.ai && aiid??>
|
||||
<#if !exchange?? || exchange == "true">
|
||||
<li><a href="/im/index.html?appid=${appid!''}&orgi=${orgi!''}&ai=false<#if aiid??>&aiid=${aiid}</#if><#if client??>&client=${client!''}</#if><#if type??>&type=text</#if><#if skill??>&skill=${skill!''}</#if><#if agent??>&agent=${agent!''}</#if><#if traceid??>&traceid=${traceid}</#if>&userid=${userid!''}&sessionid=${sessionid!''}&t=${.now?long}">人工坐席</a></li>
|
||||
</#if>
|
||||
<li class="cur"><a href="javascript:void(0)">智能客服</a></li>
|
||||
<#else>
|
||||
<li class="cur"><a href="javascript:void(0)">人工坐席</a></li>
|
||||
<li class="cur"><a href="javascript:void(0)">智能客服</a></li>
|
||||
</#if>
|
||||
</ul>
|
||||
</div>
|
||||
@ -236,12 +238,12 @@
|
||||
</div>
|
||||
|
||||
<div class="mobile-chat-bottom" id="bottom">
|
||||
<form id="imgForm" action="/im/image/upload.html?userid=${userid!''}&appid=${appid!''}&username=${username!''}&orgi=${orgi!''}" data-toggle="ajax-form"" enctype="multipart/form-data">
|
||||
<a href="javascript:;" class="imgFile" onclick="closeFaceDialog(0)">
|
||||
<img src="/im/img/img.png" class="chat-type" style="width:32px;height:32px;">
|
||||
<input type="file" name="imgFile" id="imgFile" accept="image/*" onChange="$('#imgForm').submit();$(this).val('');">
|
||||
</a>
|
||||
</form>
|
||||
<!--<form id="imgForm" action="/im/image/upload.html?userid=${userid!''}&appid=${appid!''}&username=${username!''}&orgi=${orgi!''}" data-toggle="ajax-form"" enctype="multipart/form-data">-->
|
||||
<!--<a href="javascript:;" class="imgFile" onclick="closeFaceDialog(0)">-->
|
||||
<!--<img src="/im/img/img.png" class="chat-type" style="width:32px;height:32px;">-->
|
||||
<!--<input type="file" name="imgFile" id="imgFile" accept="image/*" onChange="$('#imgForm').submit();$(this).val('');">-->
|
||||
<!--</a>-->
|
||||
<!--</form>-->
|
||||
<textarea id="message" name="content" maxlength="<#if inviteData.maxwordsnum gt 0>${inviteData.maxwordsnum}<#else>300</#if>"></textarea>
|
||||
<div class="btn-push clearfix" class="tools">
|
||||
<img id="facedialog" onclick="return openFaceDialog()" src="/im/img/face.png" style="width:32px;height:32px;"></a>
|
||||
@ -281,7 +283,7 @@
|
||||
// 参数连接
|
||||
var hostname = location.hostname ;
|
||||
var protocol = window.location.protocol.replace(/:/g,'');
|
||||
var socket = io.connect(protocol + '://'+hostname+':${port}/im/chatbot?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if agent??>&agent=${agent}</#if>');
|
||||
var socket = io(protocol + '://'+hostname+':${port}/im/chatbot?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if agent??>&agent=${agent}</#if>', {transports: ['websocket', 'polling']});
|
||||
socket.on('connect',function(){
|
||||
//service.sendRequestMessage();
|
||||
//output('<span id="callOutConnect-message">'+ new Date().format("yyyy-MM-dd hh:mm:ss") + ' 开始沟通' +'</span>' , 'message callOutConnect-message');
|
||||
@ -300,7 +302,7 @@
|
||||
var chat=document.getElementsByClassName('chatting-left').innerText;
|
||||
chat = data.message;
|
||||
if(data.messageType == "image"){
|
||||
chat = "<a href='"+data.message+"_original' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
chat = "<a href='"+data.message+"&original=true' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
}else if(data.messageType == "cooperation"){
|
||||
chat = "<a href='javascript:void(0)' onclick='acceptInvite(\""+data.message+"\", \""+data.attachmentid+"\")'>您收到一个协作邀请,点击进入协作</a>" ;
|
||||
}else if(data.messageType == "action"){
|
||||
@ -308,9 +310,9 @@
|
||||
drawCanvasImage(data.attachmentid) ;
|
||||
}
|
||||
if(data.calltype == "呼入"){
|
||||
output('<div class="chat-right"> <img class="user-img" src="/im/img/user.png" alt=""><div class="chat-message"><label class="time">'+data.createtime+'</label><label class="user">'+data.nickName+'</label> </div><div class="chatting-right"><i class="arrow arrow${inviteData.consult_dialog_color!''}"></i><div class="chat-content theme${inviteData.consult_dialog_color!''}">'+chat+'</div></div>' , "chat-block");
|
||||
output('<div class="chat-right"> <img class="user-img" src="/im/img/user.png" alt=""><div class="chat-message"><label class="time">'+data.createtime+'</label><label class="user">'+data.username+'</label> </div><div class="chatting-right"><i class="arrow arrow${inviteData.consult_dialog_color!''}"></i><div class="chat-content theme${inviteData.consult_dialog_color!''}">'+chat+'</div></div>' , "chat-block");
|
||||
}else if(data.calltype == "呼出"){
|
||||
output('<div class="chat-left"> <img class="user-img" src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>" alt=""><div class="chat-message"><label class="user">'+data.nickName+'</label><label class="time">'+data.createtime+'</label> </div><div class="chatting-left"><i class="arrow"></i><div class="chat-content">'+chat+'</div></div>' , "chat-block");
|
||||
output('<div class="chat-left"> <img class="user-img" src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>" alt=""><div class="chat-message"><label class="user">'+data.username+'</label><label class="time">'+data.createtime+'</label> </div><div class="chatting-left"><i class="arrow"></i><div class="chat-content">'+chat+'</div></div>' , "chat-block");
|
||||
}
|
||||
});
|
||||
|
||||
@ -322,7 +324,7 @@
|
||||
}
|
||||
function acceptInvite(msgid,fileid){
|
||||
document.getElementById("cooperation").style.display = "block" ;
|
||||
document.getElementById("ukefu_img_ctx").src = "/res/image.html?id=upload/"+fileid ;
|
||||
document.getElementById("ukefu_img_ctx").src = "/res/image.html?id="+fileid + "&cooperation=true&original=true";
|
||||
|
||||
$("#ukefu_img_ctx").load(function() {
|
||||
var height = document.getElementById("ukefu-image-content").offsetHeight;
|
||||
@ -346,7 +348,7 @@
|
||||
//创建新的图片对象
|
||||
var img = new Image();
|
||||
//指定图片的URL
|
||||
img.src = "/res/image.html?id=upload/" + fileid + "_cooperation";
|
||||
img.src = "/res/image.html?id=" + fileid + "&cooperation=true&original=true";
|
||||
//浏览器加载图片完毕后再绘制图片
|
||||
img.onload = function() {
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
|
@ -311,7 +311,7 @@
|
||||
<div class="chat-left">
|
||||
<img class="user-img" src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>" alt="">
|
||||
<div class="chat-message">
|
||||
<label class="user"><#if chatMessage?? && chatMessage.chatype?? && chatMessage.chatype == 'aireply'>${inviteData.ainame!'小E'}<#else>${chatMessage.username!''}</#if></label>
|
||||
<label class="user"><#if chatMessage?? && chatMessage.chatype?? && chatMessage.chatype == 'aireply'>${inviteData.ainame!'小松'}<#else>${chatMessage.username!''}</#if></label>
|
||||
<label class="time">${chatMessage.createtime!''}</label>
|
||||
</div>
|
||||
<div class="chatting-left">
|
||||
@ -452,8 +452,9 @@
|
||||
// 参数连接
|
||||
var hostname = location.hostname ;
|
||||
var protocol = window.location.protocol.replace(/:/g,'');
|
||||
var socket = io.connect(protocol + '://'+hostname+':${port}/im/user?userid=${userid!''}&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if username??>&nickname=${username}</#if><#if agent??>&agent=${agent}</#if><#if title??>&title=${title?url}</#if><#if traceid??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if>');
|
||||
var socket = io(protocol + '://'+hostname+':${port}/im/user?userid=${userid!''}&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if username??>&nickname=${username}</#if><#if agent??>&agent=${agent}</#if><#if title??>&title=${title?url}</#if><#if traceid??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if>', {transports: ['websocket', 'polling']});
|
||||
socket.on('connect',function(){
|
||||
console.log("on connect ...");
|
||||
<#if contacts?? && contacts.name??>
|
||||
socket.emit('new', {
|
||||
name : "${contacts.name!''}",
|
||||
@ -488,10 +489,11 @@
|
||||
}
|
||||
})
|
||||
socket.on('message', function(data) {
|
||||
console.log("on message", data);
|
||||
var chat=document.getElementsByClassName('chatting-left').innerText;
|
||||
chat = data.message;
|
||||
if(data.messageType == "image"){
|
||||
chat = "<a href='"+data.message+"_original' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
chat = "<a href='"+data.message+"&original=true' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
}else if(data.messageType == "file"){
|
||||
chat = "<div class='ukefu-message-file'><div class='ukefu-file-icon'><img src='/im/img/file.png'></div><div class='ukefu-file-desc'><a href='"+data.message+"' target='_blank'><div>"+data.filename+"</div><div>"+(data.filesize/1024).toFixed(3)+"Kb</div></a></div></div>" ;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<#if chatMessage.msgtype?? && chatMessage.msgtype == "image">
|
||||
<a href="${(chatMessage.message!'')?no_esc}_original" target="_blank"><img src="${(chatMessage.message!'')?no_esc}" class="ukefu-media-image"></a>
|
||||
<a href="${(chatMessage.message!'')?no_esc}&original=true" target="_blank"><img src="${(chatMessage.message!'')?no_esc}" class="ukefu-media-image"></a>
|
||||
<#elseif chatMessage.msgtype?? && chatMessage.msgtype == "cooperation">
|
||||
<a href='javascript:void(0)' onclick='acceptInvite("${chatMessage.message!''}" , "${chatMessage.attachmentid!''}")'>您收到一个协作邀请,点击进入协作</a>
|
||||
<#elseif chatMessage.msgtype?? && chatMessage.msgtype == "file">
|
||||
|
@ -174,7 +174,7 @@
|
||||
|
||||
<div class="ukefu-func-tab">
|
||||
<ul>
|
||||
<#if models?? && models["xiaoe"]?? && models["xiaoe"] == true && inviteData.ai?? && inviteData.ai == true && aiid??>
|
||||
<#if models?? && models["chatbot"]?? && models["chatbot"] == true && inviteData.ai?? && inviteData.ai == true && aiid??>
|
||||
<li><a href="/im/index.html?appid=${appid!''}&orgi=${orgi!''}<#if aiid??>&aiid=${aiid}</#if>&ai=true<#if client??>&client=${client!''}</#if><#if type??>&type=text</#if><#if skill??>&skill=${skill!''}</#if><#if agent??>&agent=${agent!''}</#if>&userid=${userid!''}&sessionid=${sessionid!''}&t=${.now?long}">智能客服</a></li>
|
||||
<li class="cur"><a href="javascript:void(0)">人工坐席</a></li>
|
||||
<#else>
|
||||
@ -223,8 +223,8 @@
|
||||
src="<#if inviteData?? && inviteData.consult_dialog_headimg??>/res/image.html?id=${inviteData.consult_dialog_headimg?url}<#else>/images/agent.png</#if>"
|
||||
alt="">
|
||||
<div class="chat-message">
|
||||
<label class="user">${chatMessage.username!''}</label> <label
|
||||
class="time">${chatMessage.createtime!''}</label>
|
||||
<label class="user"><#if chatMessage?? && chatMessage.chatype?? && chatMessage.chatype == 'aireply'>${inviteData.ainame!'小松'}<#else>${chatMessage.username!''}</#if></label>
|
||||
<label class="time">${chatMessage.createtime!''}</label>
|
||||
</div>
|
||||
<div class="chatting-left">
|
||||
<i class="arrow"></i>
|
||||
@ -281,7 +281,7 @@
|
||||
// 参数连接
|
||||
var hostname = location.hostname ;
|
||||
var protocol = window.location.protocol.replace(/:/g,'');
|
||||
var socket = io.connect(protocol + '://'+hostname+':${port}/im/user?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if agent??>&agent=${agent}</#if>');
|
||||
var socket = io(protocol + '://'+hostname+':${port}/im/user?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if username??>&nickname=${username}</#if><#if agent??>&agent=${agent}</#if>', {transports: ['websocket', 'polling']});
|
||||
socket.on('connect',function(){
|
||||
//service.sendRequestMessage();
|
||||
//output('<span id="callOutConnect-message">'+ new Date().format("yyyy-MM-dd hh:mm:ss") + ' 开始沟通' +'</span>' , 'message callOutConnect-message');
|
||||
@ -300,7 +300,7 @@
|
||||
var chat=document.getElementsByClassName('chatting-left').innerText;
|
||||
chat = data.message;
|
||||
if(data.messageType == "image"){
|
||||
chat = "<a href='"+data.message+"_original' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
chat = "<a href='"+data.message+"&original=true' target='_blank'><img src='"+data.message+"' class='ukefu-media-image'/></a>" ;
|
||||
}else if(data.messageType == "cooperation"){
|
||||
chat = "<a href='javascript:void(0)' onclick='acceptInvite(\""+data.message+"\", \""+data.attachmentid+"\")'>您收到一个协作邀请,点击进入协作</a>" ;
|
||||
}else if(data.messageType == "action"){
|
||||
@ -322,7 +322,7 @@
|
||||
}
|
||||
function acceptInvite(msgid,fileid){
|
||||
document.getElementById("cooperation").style.display = "block" ;
|
||||
document.getElementById("ukefu_img_ctx").src = "/res/image.html?id=upload/"+fileid ;
|
||||
document.getElementById("ukefu_img_ctx").src = "/res/image.html?id="+fileid + "&cooperation=true&original=true";
|
||||
|
||||
$("#ukefu_img_ctx").load(function() {
|
||||
var height = document.getElementById("ukefu-image-content").offsetHeight;
|
||||
@ -346,7 +346,7 @@
|
||||
//创建新的图片对象
|
||||
var img = new Image();
|
||||
//指定图片的URL
|
||||
img.src = "/res/image.html?id=upload/" + fileid + "_cooperation";
|
||||
img.src = "/res/image.html?id=" + fileid + "&cooperation=true&original=true";
|
||||
//浏览器加载图片完毕后再绘制图片
|
||||
img.onload = function() {
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
|
File diff suppressed because one or more lines are too long
@ -166,7 +166,7 @@
|
||||
</li>
|
||||
</#if>
|
||||
<#if user?? && user.agent == true>
|
||||
<#if (user?? && user.roleAuthMap["B01"]?? || user.usertype == "0")>
|
||||
<#if (user?? && user.roleAuthMap["A01"]?? || user.usertype == "0")>
|
||||
<li class="layui-nav-item " style="position: relative;">
|
||||
<div class="ukefu-last-msg" data-num="0" id="ukefu-last-msg">
|
||||
<small class="ukefu-msg-tip bg-red" id="msgnum">0</small>
|
||||
@ -299,15 +299,15 @@
|
||||
-->
|
||||
|
||||
|
||||
<#if models?? && models["xiaoe"]?? && models["xiaoe"] == true>
|
||||
<#if user?? &&( user.roleAuthMap["A09"]?? || user.usertype == "0") >
|
||||
<dd class="ukefu-left-menu" data-tooltip="智能机器人">
|
||||
<a href="javascript:void(0)" data-title="智能机器人" data-href="/apps/xiaoe/index.html" class="iframe_btn" data-id="maincontent" data-type="tabChange">
|
||||
<i class="kfont" style="position: relative;"></i>
|
||||
</a>
|
||||
</dd>
|
||||
</#if>
|
||||
</#if>
|
||||
<!--<#if models?? && models["xiaoe"]?? && models["xiaoe"] == true>-->
|
||||
<!--<#if user?? &&( user.roleAuthMap["A09"]?? || user.usertype == "0") >-->
|
||||
<!--<dd class="ukefu-left-menu" data-tooltip="智能机器人">-->
|
||||
<!--<a href="javascript:void(0)" data-title="智能机器人" data-href="/apps/xiaoe/index.html" class="iframe_btn" data-id="maincontent" data-type="tabChange">-->
|
||||
<!--<i class="kfont" style="position: relative;"></i>-->
|
||||
<!--</a>-->
|
||||
<!--</dd>-->
|
||||
<!--</#if>-->
|
||||
<!--</#if>-->
|
||||
<#if models?? && models["sales"]?? && models["sales"] == true>
|
||||
<#if user?? &&( user.roleAuthMap["A11"]?? || user.usertype == "0") >
|
||||
<dd class="ukefu-left-menu" data-tooltip="外呼系统">
|
||||
@ -317,10 +317,10 @@
|
||||
</dd>
|
||||
</#if>
|
||||
</#if>
|
||||
<#if models?? && models["sales"]?? && models["sales"] == true>
|
||||
<#if user?? &&( user.roleAuthMap["A11"]?? || user.usertype == "0") >
|
||||
<dd class="ukefu-left-menu" data-tooltip="机器人">
|
||||
<a href="javascript:void(0)" data-title="机器人"" data-href="/apps/chatbot/index.html" class="iframe_btn" data-id="maincontent" data-type="tabChange">
|
||||
<#if models?? && models["chatbot"]?? && models["chatbot"] == true>
|
||||
<#if user?? &&( user.roleAuthMap["A09"]?? || user.usertype == "0") >
|
||||
<dd class="ukefu-left-menu" data-tooltip="智能机器人">
|
||||
<a href="javascript:void(0)" data-title="智能机器人" data-href="/apps/chatbot/index.html" class="iframe_btn" data-id="maincontent" data-type="tabChange">
|
||||
<i class="kfont" style="position: relative;"></i>
|
||||
</a>
|
||||
</dd>
|
||||
|
@ -97,9 +97,8 @@
|
||||
<th>咨询时间</th>
|
||||
<th>服务时间</th>
|
||||
<th>等待时长</th>
|
||||
<th>服务时间</th>
|
||||
<th>服务时长</th>
|
||||
<th>地域</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<#if contacts.gender?? && contacts.gender == '-1'>未知</#if>
|
||||
</li>
|
||||
<li>
|
||||
生日:${contacts.birthday!''}
|
||||
生日:${contacts.cusbirthday!''}
|
||||
</li>
|
||||
<li>
|
||||
电话:${contacts.phone!''}
|
||||
|
@ -35,7 +35,7 @@
|
||||
<div class="layui-inline uckefu-inline">
|
||||
<label class="layui-form-label">生日:</label>
|
||||
<div class="layui-input-inline" style="padding:9px 0;">
|
||||
${contacts.birthday!''}
|
||||
${contacts.cusbirthday!''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -35,7 +35,7 @@
|
||||
<div class="layui-inline uckefu-inline">
|
||||
<label class="layui-form-label">生日:</label>
|
||||
<div class="layui-input-inline" style="padding:9px 0;">
|
||||
${contacts.birthday!''}
|
||||
${contacts.cusbirthday!''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,9 +21,9 @@
|
||||
layui.use('layer', function(){
|
||||
var layer = layui.layer;
|
||||
<#if msg?? && msg == '0'>
|
||||
layer.alert('手机或密码错误,请重新填写', {icon: 2});
|
||||
layer.alert('用户名或密码错误,请重新填写', {icon: 2});
|
||||
<#elseif msg?? && msg == '1'>
|
||||
layer.alert('用户注册成功,请使用手机和密码登陆', {icon: 1});
|
||||
layer.alert('用户注册成功,请通过用户名和密码登陆', {icon: 1});
|
||||
</#if>
|
||||
});
|
||||
layui.use('form', function(){
|
||||
@ -49,7 +49,7 @@
|
||||
<!-- <input name="username" id="username" autofocus required lay-verify="required"
|
||||
class="form-control required" value="" placeholder="用户名/邮件/手机号"> -->
|
||||
<input name="username" id="username" autofocus required lay-verify="required"
|
||||
class="form-control required" value="" placeholder="登录账号">
|
||||
class="form-control required" value="" placeholder="用户名">
|
||||
</div>
|
||||
<div class="form-group has-feedback" style="margin-bottom:10px;">
|
||||
<span class="kfont form-control-feedback"></span>
|
||||
|
@ -437,6 +437,19 @@ CREATE TABLE `cs_callout_targets` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='外呼计划目标客户';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for cs_stream_file
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `cs_stream_file`;
|
||||
CREATE TABLE `cs_stream_file` (
|
||||
`id` varchar(32) NOT NULL COMMENT '文件ID',
|
||||
`name` varchar(300) NOT NULL COMMENT '文件名称',
|
||||
`data` mediumblob NOT NULL COMMENT '原始文件',
|
||||
`thumbnail` mediumblob COMMENT '缩略图',
|
||||
`mime` varchar(200) DEFAULT NULL COMMENT '文件类型 Content Type',
|
||||
`cooperation` mediumblob COMMENT '协作文件',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT '文件';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for uk_ad_position
|
||||
@ -457,7 +470,7 @@ CREATE TABLE `uk_ad_position` (
|
||||
`AREA` text COMMENT '分类描述',
|
||||
`IMGURL` varchar(255) DEFAULT NULL COMMENT '图片URL',
|
||||
`TIPTEXT` varchar(100) DEFAULT NULL COMMENT '提示文本',
|
||||
`URL` varchar(255) DEFAULT NULL COMMENT '路径',
|
||||
`URL` text DEFAULT NULL COMMENT '路径',
|
||||
`CONTENT` text COMMENT '内容',
|
||||
`WEIGHT` int(11) DEFAULT NULL COMMENT '权重',
|
||||
`ADTYPE` varchar(50) DEFAULT NULL COMMENT '广告类型',
|
||||
@ -498,7 +511,7 @@ CREATE TABLE `uk_agentservice` (
|
||||
`lastmessage` datetime DEFAULT NULL COMMENT '最后一条消息时间',
|
||||
`waittingtimestart` datetime DEFAULT NULL COMMENT '进入排队时间',
|
||||
`lastgetmessage` datetime DEFAULT NULL COMMENT '坐席最后一条消息时间',
|
||||
`lastmsg` varchar(100) DEFAULT '' COMMENT '最后一条消息内容',
|
||||
`lastmsg` text COMMENT '最后一条消息内容',
|
||||
`agentskill` varchar(100) DEFAULT '' COMMENT '技能组',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`creater` varchar(255) DEFAULT NULL COMMENT '创建人',
|
||||
@ -637,7 +650,7 @@ CREATE TABLE `uk_agentuser` (
|
||||
`lastmessage` datetime DEFAULT NULL COMMENT '最后一条消息时间',
|
||||
`waittingtimestart` datetime DEFAULT NULL COMMENT '进入队列时间',
|
||||
`lastgetmessage` datetime DEFAULT NULL COMMENT '最后一条消息时间',
|
||||
`lastmsg` varchar(100) DEFAULT '' COMMENT '最后一条消息',
|
||||
`lastmsg` text COMMENT '最后一条消息',
|
||||
`agentskill` varchar(100) DEFAULT '' COMMENT '技能组',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`creater` varchar(255) DEFAULT NULL COMMENT '创建人',
|
||||
@ -676,7 +689,7 @@ CREATE TABLE `uk_agentuser` (
|
||||
`avgreplytime` int(11) DEFAULT '0' COMMENT '平均回复时长',
|
||||
`sessionid` varchar(32) DEFAULT NULL COMMENT '会话ID',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`url` varchar(255) DEFAULT NULL COMMENT 'URL',
|
||||
`url` text DEFAULT NULL COMMENT 'URL',
|
||||
`traceid` varchar(32) DEFAULT NULL COMMENT '跟踪ID',
|
||||
`agenttimeout` int(11) DEFAULT '0' COMMENT '坐席超时时长',
|
||||
`agenttimeouttimes` int(11) DEFAULT '0' COMMENT '坐席超时次数',
|
||||
@ -781,7 +794,7 @@ CREATE TABLE `uk_attachment_file` (
|
||||
`organ` varchar(32) DEFAULT NULL COMMENT '组织机构ID',
|
||||
`datastatus` tinyint(4) DEFAULT NULL COMMENT '数据状态(逻辑删除)',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`url` varchar(255) CHARACTER SET utf32 DEFAULT NULL COMMENT '地址',
|
||||
`url` text CHARACTER SET utf32 DEFAULT NULL COMMENT '地址',
|
||||
`updatetime` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`filelength` int(11) DEFAULT NULL COMMENT '文件长度',
|
||||
`filetype` varchar(255) DEFAULT NULL COMMENT '文件类型',
|
||||
@ -1610,7 +1623,7 @@ CREATE TABLE `cs_contact_notes` (
|
||||
`createtime` datetime NOT NULL COMMENT '创建时间',
|
||||
`updatetime` datetime NOT NULL COMMENT '更新时间',
|
||||
`category` varchar(200) DEFAULT NULL COMMENT '内容类型',
|
||||
`content` varchar(1000) DEFAULT NULL COMMENT '内容',
|
||||
`content` text COMMENT '内容',
|
||||
`creater` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||
`datastatus` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
`agentuser` varchar(32) DEFAULT NULL COMMENT '在线访客记录ID',
|
||||
@ -2112,7 +2125,7 @@ CREATE TABLE `uk_inviterecord` (
|
||||
`responsetime` int(11) DEFAULT NULL COMMENT '响应时间',
|
||||
`appid` varchar(32) DEFAULT NULL COMMENT 'SNSID',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`url` varchar(255) DEFAULT NULL COMMENT '地址',
|
||||
`url` text DEFAULT NULL COMMENT '地址',
|
||||
`traceid` varchar(32) DEFAULT NULL COMMENT '跟踪ID',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='邀请记录表';
|
||||
@ -2481,7 +2494,7 @@ CREATE TABLE `uk_onlineuser` (
|
||||
`keyword` varchar(100) DEFAULT NULL COMMENT '搜索引擎关键词',
|
||||
`source` varchar(50) DEFAULT NULL COMMENT '来源',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`url` varchar(255) DEFAULT NULL COMMENT '来源URL',
|
||||
`url` text DEFAULT NULL COMMENT '来源URL',
|
||||
`useragent` text COMMENT 'UA',
|
||||
`invitetimes` int(11) DEFAULT NULL COMMENT '要求次数',
|
||||
`invitestatus` varchar(10) DEFAULT NULL COMMENT '邀请状态',
|
||||
@ -2541,7 +2554,7 @@ CREATE TABLE `uk_onlineuser_his` (
|
||||
`keyword` varchar(100) DEFAULT NULL COMMENT '搜索引擎关键词',
|
||||
`source` varchar(50) DEFAULT NULL COMMENT '来源',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`url` varchar(255) DEFAULT NULL COMMENT '来源URL',
|
||||
`url` text DEFAULT NULL COMMENT '来源URL',
|
||||
`useragent` text COMMENT 'UA',
|
||||
`invitetimes` int(11) DEFAULT NULL COMMENT '要求次数',
|
||||
`invitestatus` varchar(10) DEFAULT NULL COMMENT '邀请状态',
|
||||
@ -2914,7 +2927,7 @@ CREATE TABLE `uk_recentuser` (
|
||||
`name` varchar(100) DEFAULT NULL COMMENT '名称',
|
||||
`orgi` varchar(100) DEFAULT NULL COMMENT '租户ID',
|
||||
`user_id` varchar(32) DEFAULT NULL COMMENT '用户ID',
|
||||
`lastmsg` varchar(100) DEFAULT NULL COMMENT '最后一条消息',
|
||||
`lastmsg` text COMMENT '最后一条消息',
|
||||
`newmsg` int(11) DEFAULT NULL COMMENT '未读消息数量',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='公共已读消息';
|
||||
@ -3475,7 +3488,7 @@ CREATE TABLE `uk_sysdic` (
|
||||
`DICID` varchar(32) DEFAULT NULL COMMENT '目录ID',
|
||||
`DEFAULTVALUE` tinyint(4) DEFAULT NULL COMMENT '默认值',
|
||||
`DISCODE` tinyint(4) DEFAULT NULL COMMENT '编码',
|
||||
`URL` varchar(255) DEFAULT NULL COMMENT '系统权限资源的URL',
|
||||
`URL` text DEFAULT NULL COMMENT '系统权限资源的URL',
|
||||
`MODULE` varchar(32) DEFAULT NULL COMMENT '权限资源所属模块',
|
||||
`MLEVEL` varchar(32) DEFAULT NULL COMMENT '菜单级别(一级/二级)',
|
||||
`RULES` varchar(100) DEFAULT NULL,
|
||||
@ -7130,9 +7143,7 @@ INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce8b990057e', '在线坐
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce8e6a2057f', '全部坐席', 'pub', 'A08_A04_A02', NULL, 'auth', '402881ef612b1f5b01612cdd1e930570', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:41:56', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/service/user/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce964ae0580', '智能机器人', 'pub', 'A09_A01', NULL, 'auth', '402881ef612b1f5b01612cc602450546', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:42:28', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, 'javascript:;', 'webim', '2', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce996f80581', '语料库配置', 'pub', 'A09_A02', NULL, 'auth', '402881ef612b1f5b01612cc602450546', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:42:41', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, 'javascript:;', 'webim', '2', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce9d8150582', '机器人选项', 'pub', 'A09_A01_A01', NULL, 'auth', '402881ef612b1f5b01612ce964ae0580', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:42:58', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cea04810583', '对话测试', 'pub', 'A09_A01_A02', NULL, 'auth', '402881ef612b1f5b01612ce964ae0580', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:43:09', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/chat.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cea430f0584', '用户提问历史', 'pub', 'A09_A01_A03', NULL, 'auth', '402881ef612b1f5b01612ce964ae0580', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:43:25', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/history.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ce9d8150582', '机器人管理', 'pub', 'A09_A01_A01', NULL, 'auth', '402881ef612b1f5b01612ce964ae0580', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:42:58', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ceaff050587', '对话场景', 'pub', 'A09_A02_A03', NULL, 'auth', '402881ef612b1f5b01612ce996f80581', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:44:13', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/scene.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ced9d5f0588', '知识维护', 'pub', 'A09_A02_A01', NULL, 'auth', '402881ef612b1f5b01612ce996f80581', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:47:05', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/knowledge.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cedca5e0589', '词库配置', 'pub', 'A09_A02_A02', NULL, 'auth', '402881ef612b1f5b01612ce996f80581', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:47:16', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/xiaoe/words.html', 'webim', '3', NULL, 'left');
|
||||
@ -7146,7 +7157,6 @@ INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cefb4120590', '语音留
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612ceffa060591', '漏话列表', 'pub', 'A10_A01_A06', NULL, 'auth', '402881ef612b1f5b01612cee4fbb058a', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:49:40', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/callcenter/misscall/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cf03d740592', '在线坐席', 'pub', 'A10_A02_A01', NULL, 'auth', '402881ef612b1f5b01612cee80ed058b', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:49:57', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/callcenter/online/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cf065f40593', '全部坐席', 'pub', 'A10_A02_A02', NULL, 'auth', '402881ef612b1f5b01612cee80ed058b', NULL, NULL, '�', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:50:07', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/apps/callcenter/agents/index.html', 'webim', '3', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cf11a140594', '坐席工作台', 'pub', 'B01', NULL, 'auth', '402888815d2fe37f015d2fe75cc80002', NULL, NULL, '', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:50:53', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/agent/index.html', 'webim', '1', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881ef612b1f5b01612cf147810595', '系统管理', 'pub', 'B02', NULL, 'auth', '402888815d2fe37f015d2fe75cc80002', NULL, NULL, '<i class=\"layui-icon\" style=\"position: relative;\"></i>', NULL, NULL, '297e8c7b455798280145579c73e501c1', '2018-01-25 18:51:05', NULL, 0, 0, '402888815d2fe37f015d2fe75cc80002', 0, 0, '/admin/content.html', 'webim', '1', NULL, 'left');
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881fb61e49a9a0161e4a8a1260392', '过滤器类型', 'pub', 'com.dic.filter.modeltype', NULL, 'data', '0', '', NULL, NULL, NULL, NULL, '4028cac3614cd2f901614cf8be1f0324', '2018-03-02 11:01:52', NULL, 1, 0, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `uk_sysdic` VALUES ('402881fb61e49a9a0161e4a925a20393', '过滤器取值方式', 'pub', 'com.dic.filter.convalue', NULL, 'data', '0', '', NULL, NULL, NULL, NULL, '4028cac3614cd2f901614cf8be1f0324', '2018-03-02 11:02:25', NULL, 1, 0, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL);
|
||||
@ -7752,7 +7762,7 @@ CREATE TABLE `uk_system_message` (
|
||||
`SECLEV` varchar(50) DEFAULT NULL COMMENT '启用SSL',
|
||||
`SSLPORT` varchar(50) DEFAULT NULL COMMENT 'SSL端口',
|
||||
`ORGI` varchar(32) DEFAULT NULL COMMENT '租户ID',
|
||||
`URL` varchar(255) DEFAULT NULL COMMENT 'URL',
|
||||
`URL` text DEFAULT NULL COMMENT 'URL',
|
||||
`smstype` varchar(32) DEFAULT NULL COMMENT '短信类型',
|
||||
`APPKEY` varchar(200) DEFAULT NULL COMMENT 'APPKEY',
|
||||
`APPSEC` varchar(200) DEFAULT NULL COMMENT 'APPSEC',
|
||||
@ -7837,7 +7847,7 @@ CREATE TABLE `uk_systemconfig` (
|
||||
-- Records of uk_systemconfig
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `uk_systemconfig` VALUES ('2c93809364e0a6d00164ef6722270582', NULL, '春松客服-全渠道智能客服', NULL, 'cskefu', NULL, NULL, NULL, NULL, 'www.chatopera.com', NULL, NULL, '4028cac3614cd2f901614cf8be1f0324', '2018-07-31 08:14:30', NULL, NULL, NULL, NULL, NULL, '01', 'info', 0, NULL, NULL, '', 0, 0, '', '', '', '', '', '', NULL, 0, 0, 0, 0, '', '', NULL, NULL, '', '', NULL, 0, 0, NULL, NULL, NULL, 0, '', NULL, 0, 0, '租户', 0, 0, NULL, NULL, NULL);
|
||||
INSERT INTO `uk_systemconfig` VALUES ('2c93809364e0a6d00164ef6722270582', NULL, '春松客服-全渠道智能客服', NULL, 'cskefu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '4028cac3614cd2f901614cf8be1f0324', '2018-07-31 08:14:30', NULL, NULL, NULL, NULL, NULL, '01', 'info', 0, NULL, NULL, '', 0, 0, '', '', '', '', '', '', NULL, 0, 0, 0, 0, '', '', NULL, NULL, '', '', NULL, 0, 0, NULL, NULL, NULL, 0, '', NULL, 0, 0, '租户', 0, 0, NULL, NULL, NULL);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -8179,7 +8189,7 @@ CREATE TABLE `uk_userevent` (
|
||||
`city` varchar(32) DEFAULT NULL COMMENT '城市',
|
||||
`isp` varchar(32) DEFAULT NULL COMMENT '运营商',
|
||||
`province` varchar(32) DEFAULT NULL COMMENT '省份',
|
||||
`url` varchar(255) DEFAULT NULL COMMENT '接入URL',
|
||||
`url` text DEFAULT NULL COMMENT '接入URL',
|
||||
`sessionid` varchar(32) DEFAULT NULL COMMENT '会话ID',
|
||||
`param` text COMMENT '请求参数',
|
||||
`times` int(11) DEFAULT NULL COMMENT '访问次数',
|
||||
|
Loading…
x
Reference in New Issue
Block a user