1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

Merge pull request #1 from chatopera/osc

2020年10月14日 同步
This commit is contained in:
Enze 2020-10-14 16:07:55 +08:00 committed by GitHub
commit 3990a86c9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 392 additions and 188 deletions

134
README.md
View File

@ -2,31 +2,23 @@
<p align="center">
<b>春松客服QQ交流群185659917 <a href="https://jq.qq.com/?_wv=1027&k=5I1cJLP" target="_blank">点击链接加入群聊</a></b><br>
<img src="https://user-images.githubusercontent.com/3538629/44917177-432d9700-ad6a-11e8-9420-46b0281073e6.png" width="200">
<img src="https://static-public.chatopera.com/assets/images/44917177-432d9700-ad6a-11e8-9420-46b0281073e6.png" width="200">
</p>
# 春松客服: 多渠道智能客服
春松客服帮助企业快速而低成本的获得好用的智能客服系统。
<img src="https://user-images.githubusercontent.com/3538629/61031891-fc311900-a3f2-11e9-80cf-c8d0700538a0.png" width="600">
<img src="https://static-public.chatopera.com/assets/images/61031891-fc311900-a3f2-11e9-80cf-c8d0700538a0.png" width="600">
春松客服是 Chatopera 自主研发以及基于且增强其它开源软件的方式实现的,春松客服会不断增强客服系统的智能化,这包括利用自然语言处理、机器学习和语音识别等技术让客服工作更有效率、客服满意度更高、成本更低。
**开源项目地址:** [https://github.com/chatopera/cosin](https://github.com/chatopera/cosin)
**开源项目地址:** [https://gitee.com/chatopera/cosin](https://gitee.com/chatopera/cosin)
**开发环境搭建:** [https://docs.chatopera.com/products/cskefu/engineering.html](https://docs.chatopera.com/products/cskefu/engineering.html)
**春松客服团队博客:** [https://blog.chatopera.com/](https://blog.chatopera.com/)
## 内容结构
| | | |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [产品文档](https://docs.chatopera.com/products/cskefu/index.html) | [在线培训课程](https://github.com/chatopera/cosin#%E5%9C%A8%E7%BA%BF%E5%9F%B9%E8%AE%AD%E8%AF%BE%E7%A8%8B) | [用户案例](https://github.com/chatopera/cosin#%E7%94%A8%E6%88%B7%E6%A1%88%E4%BE%8B) |
| [开发文档](https://github.com/chatopera/cosin#%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3) | [产品截图](https://github.com/chatopera/cosin#%E4%BA%A7%E5%93%81%E6%88%AA%E5%9B%BE) | [产品演示](https://github.com/chatopera/cosin#%E4%BA%A7%E5%93%81%E6%BC%94%E7%A4%BA) |
| [立即部署](https://github.com/chatopera/cosin#%E7%AB%8B%E5%8D%B3%E9%83%A8%E7%BD%B2) | [鸣谢](https://github.com/chatopera/cosin#%E9%B8%A3%E8%B0%A2) | [开源许可协议](https://github.com/chatopera/cosin#%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE) |
## 产品演示
- 坐席工作台
@ -55,7 +47,7 @@
- 坐席工作台:汇聚多渠道访客请求,坐席根据策略自动分配,自动弹屏,转接等
- 机器人客服:集成 Chatopera 云服务,通过插件形式安装,插件也以开源形式提供,[查看插件源码](./public/plugins)。
- 机器人客服:集成 [Chatopera 云服务](https://bot.chatopera.com)利用 Chatopera 强大的聊天机器人解决方案,提升客户服务工作中的自动化、智能化;机器人客服插件既能通过知识库联想,知识库快捷支持坐席人员,也可以直接为访客提供查询、数据收集等功能;通过插件形式安装,插件也以开源形式提供,[查看插件源码](./public/plugins)。
- 企业聊天:支持企业员工在春松客服系统中群聊和私聊
@ -84,7 +76,7 @@
<p align="center">
<b><a href="https://docs.chatopera.com/products/cskefu/training.html" target="_blank">主讲老师介绍</a></b><br>
<a href="https://docs.chatopera.com/products/cskefu/training.html" target="_blank">
<img src="https://user-images.githubusercontent.com/3538629/71793716-fd2cc580-3078-11ea-99b1-d86dba4475ae.png" width="800">
<img src="https://static-public.chatopera.com/assets/images/djt-teacher-hain.jpg" width="800">
</a>
</p>
@ -93,11 +85,11 @@
<p align="center">
<b><a href="https://www.chatopera.com/customer.html" target="_blank">TA们都选择春松客服</a></b><br>
<a href="https://www.chatopera.com/customer.html" target="_blank">
<img src="https://user-images.githubusercontent.com/3538629/71613944-f7039880-2be3-11ea-8287-9e82f09e436f.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/71613944-f7039880-2be3-11ea-8287-9e82f09e436f.png" width="900">
</a>
</p>
## 社区这样评价春松客服
## 企业用户这样评价我们
```
The collaboration is efficient, very professional. The software is steady with high quality services.
@ -122,58 +114,78 @@ The collaboration is efficient, very professional. The software is steady with h
<p align="center">
<b><a href="https://docs.chatopera.com/products/cskefu/engineering.html" target="_blank">开发文档</a></b><br>
<a href="https://docs.chatopera.com/products/cskefu/engineering.html" target="_blank">
<img src="https://user-images.githubusercontent.com/3538629/44992890-38be0800-afcb-11e8-8fde-a5a671d29764.png" width="300">
<img src="https://static-public.chatopera.com/assets/images/44992890-38be0800-afcb-11e8-8fde-a5a671d29764.png" width="300">
</a>
</p>
## 寻找开发者
寻找开发者合作智能客服项目,社区共建,携手共赢!
* 组织或个人,在春松客服主页展示为认证开发者
* 春松客服官方推荐项目机会
* 专访并通过官方渠道曝光
填写申请:[https://www.wjx.top/jq/93397428.aspx](https://www.wjx.top/jq/93397428.aspx)
## 产品截图
<p align="center">
<b>欢迎页</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44915395-6bff5d80-ad65-11e8-817a-8abb812fb5ee.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44915395-6bff5d80-ad65-11e8-817a-8abb812fb5ee.png" width="900">
</p>
<details>
<summary>展开查看更多产品截图</summary>
<p>
<p align="center">
<b>坐席工作台</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44915582-eb8d2c80-ad65-11e8-8876-86c8b5bb5cc7.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44915582-eb8d2c80-ad65-11e8-8876-86c8b5bb5cc7.png" width="900">
</p>
<p align="center">
<b>坐席监控</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44915711-432b9800-ad66-11e8-899b-1ea02244925d.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44915711-432b9800-ad66-11e8-899b-1ea02244925d.png" width="900">
</p>
<p align="center">
<b>外呼计划</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44915831-ab7a7980-ad66-11e8-88a5-a2cd23b8c689.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44915831-ab7a7980-ad66-11e8-88a5-a2cd23b8c689.png" width="900">
</p>
<p align="center">
<b>通话记录</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44915218-feebc800-ad64-11e8-90fc-36ce96b0c09a.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44915218-feebc800-ad64-11e8-90fc-36ce96b0c09a.png" width="900">
</p>
<p align="center">
<b>集成客服机器人</b><br>
<img src="https://user-images.githubusercontent.com/3538629/51080565-4b82df00-1719-11e9-8cc4-dbbec0459224.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/51080565-4b82df00-1719-11e9-8cc4-dbbec0459224.png" width="900">
</p>
<p align="center">
<b>客服机器人应答</b><br>
<img src="https://user-images.githubusercontent.com/3538629/51080567-50479300-1719-11e9-85d8-d209370c9d10.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/51080567-50479300-1719-11e9-85d8-d209370c9d10.png" width="900">
</p>
<p align="center">
<b>更多功能,敬请期待 ...</b><br>
<img src="https://user-images.githubusercontent.com/3538629/44916014-28a5ee80-ad67-11e8-936a-a2cdbe62f529.png" width="900">
<img src="https://static-public.chatopera.com/assets/images/44916014-28a5ee80-ad67-11e8-936a-a2cdbe62f529.png" width="900">
</p>
</p>
</details>
## 立即部署
- 私有部署版
参考部署[开源社区版本文档](https://docs.chatopera.com/products/cskefu/deploy.html)。
## 鸣谢
[FreeSWITCH 中国社区](http://www.freeswitch.org.cn/)
@ -182,9 +194,79 @@ The collaboration is efficient, very professional. The software is steady with h
Copyright (2018-2020) <a href="https://www.chatopera.com/" target="_blank">北京华夏春松科技有限公司</a>
[Apache License Version 2.0](https://github.com/chatopera/cosin/blob/master/LICENSE)
[Apache License Version 2.0](https://gitee.com/chatopera/cosin/blob/master/LICENSE)
[![chatoper banner][co-banner-image]][co-url]
[co-banner-image]: https://user-images.githubusercontent.com/3538629/42383104-da925942-8168-11e8-8195-868d5fcec170.png
[co-banner-image]: https://static-public.chatopera.com/assets/images/42383104-da925942-8168-11e8-8195-868d5fcec170.png
[co-url]: https://www.chatopera.com
## Chatopera 云服务
[https://bot.chatopera.com/](https://bot.chatopera.com/)
[Chatopera 云服务](https://bot.chatopera.com)是一站式实现聊天机器人的云服务按接口调用次数计费。Chatopera 云服务是 [Chatopera 机器人平台](https://docs.chatopera.com/products/chatbot-platform/index.html)的软件即服务实例。在云计算基础上Chatopera 云服务属于**聊天机器人即服务**的云服务。
Chatopera 机器人平台包括知识库、多轮对话、意图识别和语音识别等组件,标准化聊天机器人开发,支持企业 OA 智能问答、HR 智能问答、智能客服和网络营销等场景。企业 IT 部门、业务部门借助 Chatopera 云服务快速让聊天机器人上线!
<details>
<summary>展开查看 Chatopera 云服务的产品截图</summary>
<p>
<p align="center">
<b>自定义词典</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530072-da92d600-d33e-11e9-8656-01c26caff4f9.png" width="800">
</p>
<p align="center">
<b>自定义词条</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530091-e41c3e00-d33e-11e9-9704-c07a2a02b84e.png" width="800">
</p>
<p align="center">
<b>创建意图</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530169-12018280-d33f-11e9-93b4-9db881cf4dd5.png" width="800">
</p>
<p align="center">
<b>添加说法和槽位</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530187-20e83500-d33f-11e9-87ec-a0241e3dac4d.png" width="800">
</p>
<p align="center">
<b>训练模型</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530235-33626e80-d33f-11e9-8d07-fa3ae417fd5d.png" width="800">
</p>
<p align="center">
<b>测试对话</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530253-3d846d00-d33f-11e9-81ea-86e6d47020d8.png" width="800">
</p>
<p align="center">
<b>机器人画像</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530312-6442a380-d33f-11e9-869c-85fb6a835a97.png" width="800">
</p>
<p align="center">
<b>系统集成</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530281-4ecd7980-d33f-11e9-8def-c53251f30138.png" width="800">
</p>
<p align="center">
<b>聊天历史</b><br>
<img src="https://static-public.chatopera.com/assets/images/64530295-5856e180-d33f-11e9-94d4-db50481b2d8e.png" width="800">
</p>
</p>
</details>
<p align="center">
<b>立即使用</b><br>
<a href="https://bot.chatopera.com" target="_blank">
<img src="https://static-public.chatopera.com/assets/images/64531083-3199aa80-d341-11e9-86cd-3a3ed860b14b.png" width="800">
</a>
</p>

View File

@ -373,7 +373,7 @@
<dependency>
<groupId>com.chatopera.bot</groupId>
<artifactId>sdk</artifactId>
<version>2.1.0</version>
<version>3.1.0</version>
</dependency>
</dependencies>

View File

@ -54,6 +54,10 @@ public class ApplicationController extends Handler {
@Autowired
private Cache cache;
@Value("${tongji.baidu.sitekey}")
private String tongjiBaiduSiteKey;
@RequestMapping("/")
public ModelAndView admin(HttpServletRequest request) {
// logger.info("[admin] path {} queryString {}", request.getPathInfo(),request.getQueryString());
@ -85,6 +89,12 @@ public class ApplicationController extends Handler {
}
}
view.addObject("agentStatus", cache.findOneAgentStatusByAgentnoAndOrig(logined.getId(), logined.getOrgi()));
if (StringUtils.isNotBlank(tongjiBaiduSiteKey) && !StringUtils.equalsIgnoreCase(tongjiBaiduSiteKey, "placeholder")) {
logger.info("tongjiBaiduSiteKey: {}", tongjiBaiduSiteKey);
view.addObject("tongjiBaiduSiteKey", tongjiBaiduSiteKey);
}
return view;
}

View File

@ -39,6 +39,7 @@ import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
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.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
@ -90,6 +91,12 @@ public class LoginController extends Handler {
@Autowired
private ACDWorkMonitor acdWorkMonitor;
@Value("${tongji.baidu.sitekey}")
private String tongjiBaiduSiteKey;
@Value("${ads.login.banner}")
private String adsLoginBanner;
/**
* 登录页面
*
@ -149,6 +156,15 @@ public class LoginController extends Handler {
if (systemConfig != null) {
view.addObject("systemConfig", systemConfig);
}
if (StringUtils.isNotBlank(tongjiBaiduSiteKey) && !StringUtils.equalsIgnoreCase(tongjiBaiduSiteKey, "placeholder")) {
view.addObject("tongjiBaiduSiteKey", tongjiBaiduSiteKey);
}
if(StringUtils.isNotBlank(adsLoginBanner) && StringUtils.equalsIgnoreCase(adsLoginBanner, "on")){
view.addObject("adsLoginBanner", "on");
}
return view;
}
@ -211,14 +227,14 @@ public class LoginController extends Handler {
// 工作状态记录
acdWorkMonitor.recordAgentStatus(agentStatus.getAgentno(),
agentStatus.getUsername(),
agentStatus.getAgentno(),
user.isAdmin(), // 0代表admin
agentStatus.getAgentno(),
MainContext.AgentStatusEnum.OFFLINE.toString(),
MainContext.AgentStatusEnum.READY.toString(),
MainContext.AgentWorkType.MEIDIACHAT.toString(),
orgi, null);
agentStatus.getUsername(),
agentStatus.getAgentno(),
user.isAdmin(), // 0代表admin
agentStatus.getAgentno(),
MainContext.AgentStatusEnum.OFFLINE.toString(),
MainContext.AgentStatusEnum.READY.toString(),
MainContext.AgentWorkType.MEIDIACHAT.toString(),
orgi, null);
} catch (Exception e) {
logger.error("[login] set agent status", e);

View File

@ -67,7 +67,7 @@ public class TemplateController extends Handler{
@Menu(type = "admin" , subtype = "template" , access = false , admin = true)
public void expall(ModelMap map , HttpServletRequest request , HttpServletResponse response) throws Exception {
List<Template> templateList = templateRes.findByOrgi(super.getOrgi(request)) ;
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Template-Export-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".data");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Template-Export-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".data");
response.getOutputStream().write(MainUtils.toBytes(templateList));
return ;
}

View File

@ -355,7 +355,7 @@ public class CustomerController extends Handler {
values.add(MainUtils.transBean2Map(customer));
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
excelProcess.process();
@ -382,7 +382,7 @@ public class CustomerController extends Handler {
values.add(MainUtils.transBean2Map(customer));
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
excelProcess.process();
@ -413,7 +413,7 @@ public class CustomerController extends Handler {
values.add(MainUtils.transBean2Map(customer));
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-EntCustomer-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
excelProcess.process();

View File

@ -281,7 +281,7 @@ public class IMController extends Handler {
/**
* 查询坐席 缓存
*/
view.addObject("agentList", OnlineUserProxy.agents(MainContext.SYSTEM_ORGI, true));
view.addObject("agentList", OnlineUserProxy.agents(MainContext.SYSTEM_ORGI));
}
view.addObject("traceid", userHistory.getId());

View File

@ -282,7 +282,7 @@ public class QuickReplyController extends Handler {
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -303,7 +303,7 @@ public class QuickReplyController extends Handler {
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
@ -324,7 +324,7 @@ public class QuickReplyController extends Handler {
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-QuickReply-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;

View File

@ -425,7 +425,7 @@ public class TopicController extends Handler{
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
@ -446,7 +446,7 @@ public class TopicController extends Handler{
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;

View File

@ -286,7 +286,7 @@ public class ReportController extends Handler{
values.add(MainUtils.transBean2Map(topic)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Report-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -307,7 +307,7 @@ public class ReportController extends Handler{
values.add(MainUtils.transBean2Map(report)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Report-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
if(table!=null){
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;

View File

@ -161,7 +161,7 @@ public class AgentSummaryController extends Handler{
values.add(MainUtils.transBean2Map(event)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -182,7 +182,7 @@ public class AgentSummaryController extends Handler{
values.add(MainUtils.transBean2Map(statusEvent)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -220,7 +220,7 @@ public class AgentSummaryController extends Handler{
values.add(MainUtils.transBean2Map(summary)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
MetadataTable table = metadataRes.findByTablename("uk_servicesummary") ;

View File

@ -169,7 +169,7 @@ public class ProcessedSummaryController extends Handler{
values.add(MainUtils.transBean2Map(event)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -190,7 +190,7 @@ public class ProcessedSummaryController extends Handler{
values.add(MainUtils.transBean2Map(statusEvent)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
excelProcess.process();
@ -233,7 +233,7 @@ public class ProcessedSummaryController extends Handler{
values.add(MainUtils.transBean2Map(summary)) ;
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Summary-History-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");
MetadataTable table = metadataRes.findByTablename("uk_servicesummary") ;

View File

@ -100,7 +100,7 @@ public class StatsController extends Handler {
/**
* 查询坐席 缓存
*/
map.addAttribute("agentList", OnlineUserProxy.agents(super.getOrgi(request), true));
map.addAttribute("agentList", OnlineUserProxy.agents(super.getOrgi(request)));
return request(super.createAppsTempletResponse("/apps/service/stats/coment"));
}
@ -121,7 +121,7 @@ public class StatsController extends Handler {
}
}
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Report-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
new UKExcelUtil(reportData, response.getOutputStream(), "满意度统计").createFile();
return;
@ -154,7 +154,7 @@ public class StatsController extends Handler {
/**
* 查询坐席 缓存
*/
map.addAttribute("agentList", OnlineUserProxy.agents(super.getOrgi(request), true));
map.addAttribute("agentList", OnlineUserProxy.agents(super.getOrgi(request)));
return request(super.createAppsTempletResponse("/apps/service/stats/consult"));
}
@ -165,7 +165,7 @@ public class StatsController extends Handler {
Map<String, Object> mapR = MainUtils.getRequestParam(request);
mapR.put("orgi", super.getOrgi(request));
ReportData reportData = new CubeService("consult.xml", path, dataSource, mapR).execute("SELECT {[Measures].[咨询数量],[Measures].[平均等待时长(秒)],[Measures].[平均咨询时长(秒)]} on columns , NonEmptyCrossJoin([time].[日期].members , NonEmptyCrossJoin([skill].[技能组].members,[agent].[坐席].members)) on rows FROM [咨询]");
response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
response.setHeader("content-disposition", "attachment;filename=CSKeFu-Report-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");
new UKExcelUtil(reportData, response.getOutputStream(), "客服坐席统计").createFile();
return;

View File

@ -63,6 +63,7 @@ public class OnlineUserProxy {
private static AgentUserContactsRepository agentUserContactsRes;
private static ContactsRepository contactsRes;
private static UserProxy userProxy;
private static OrganRepository organRes;
/**
* @param id
@ -325,47 +326,36 @@ public class OnlineUserProxy {
/**
* @param orgi
* @param isJudgeShare
* @param orgi 一个坐席可以添加到多个组织原租户共享功能废弃
* @return
*/
@SuppressWarnings("unchecked")
public static List<User> agents(String orgi, boolean isJudgeShare) {
public static List<User> agents(String orgi) {
String origOrig = orgi;
boolean isShare = false;
if (isJudgeShare) {
SystemConfig systemConfig = MainUtils.getSystemConfig();
if (systemConfig != null && systemConfig.isEnabletneant() && systemConfig.isTenantshare()) {
orgi = MainContext.SYSTEM_ORGI;
isShare = true;
}
}
List<User> agentList = getCache().findOneSystemByIdAndOrgi(Constants.CACHE_AGENT + origOrig, origOrig);
List<User> agentTempList = null;
if (agentList == null) {
agentList = getUserRes().findByOrgiAndAgentAndDatastatus(orgi, true, false);
agentTempList = new ArrayList<User>();
// 共享的话 查出绑定的组织
if (isShare) {
List<OrgiSkillRel> orgiSkillRelList = getOrgiSkillRelRes().findByOrgi(origOrig);
if (!orgiSkillRelList.isEmpty()) {
for (User user : agentList) {
// TODO 此处的查询处理比较多应使用缓存
// 一个用户可隶属于多个组织
getUserProxy().attachOrgansPropertiesForUser(user);
for (OrgiSkillRel rel : orgiSkillRelList) {
if (user.getOrgans().size() > 0 && user.inAffiliates(rel.getSkillid())) {
agentTempList.add(user);
}
}
List<User> agentList = getUserRes().findByOrgiAndAgentAndDatastatus(orgi, true, false);
List<User> agentTempList = new ArrayList<User>();
List<Organ> skillOrgansByOrgi = getOrganRes().findByOrgiAndSkill(origOrig, true);
if (!skillOrgansByOrgi.isEmpty()) {
for (User user : agentList) {
// 跳过管理员角色用户不显示在技能组列表
if (user.isAdmin() || user.isSuperadmin()) continue;
// 只显示在线的客服跳过离线的客服
if (getCache().findOneAgentStatusByAgentnoAndOrig(user.getId(), origOrig) == null) continue;
// 一个用户可隶属于多个组织
getUserProxy().attachOrgansPropertiesForUser(user);
for (Organ organ : skillOrgansByOrgi) {
if (user.getOrgans().size() > 0 && user.inAffiliates(organ.getId())) {
agentTempList.add(user);
}
}
agentList = agentTempList;
}
if (agentList.size() > 0) {
getCache().putSystemListByIdAndOrgi(Constants.CACHE_AGENT + origOrig, origOrig, agentList);
}
}
agentList = agentTempList;
return agentList;
}
@ -508,7 +498,7 @@ public class OnlineUserProxy {
onlineUser.setOlduser("1");
}
onlineUser.setMobile(MobileDevice.isMobile(request
.getHeader("User-Agent")) ? "1" : "0");
.getHeader("User-Agent")) ? "1" : "0");
// onlineUser.setSource(user.getId());
@ -546,10 +536,10 @@ public class OnlineUserProxy {
onlineUser.setCity(ipdata.getCity());
onlineUser.setIsp(ipdata.getIsp());
onlineUser.setRegion(ipdata.toString() + ""
+ ip + "");
+ ip + "");
onlineUser.setDatestr(new SimpleDateFormat("yyyMMdd")
.format(now));
.format(now));
onlineUser.setHostname(ip);
onlineUser.setSessionid(sessionid);
@ -1030,6 +1020,13 @@ public class OnlineUserProxy {
return userRes;
}
private static OrganRepository getOrganRes() {
if (organRes == null) {
organRes = MainContext.getContext().getBean(OrganRepository.class);
}
return organRes;
}
private static OrgiSkillRelRepository getOrgiSkillRelRes() {
if (orgiSkillRelRes == null) {
orgiSkillRelRes = MainContext.getContext().getBean(OrgiSkillRelRepository.class);

View File

@ -185,6 +185,7 @@ cskefu.callout.watch.interval=60000
# 企业聊天机器人
##############################################
bot.baseurl=https://bot.chatopera.com
ads.login.banner=placeholder
##############################################
# 业务功能相关设置
@ -228,4 +229,14 @@ endpoints.loggers.enabled=false
endpoints.configprops.enabled=false
endpoints.mappings.enabled=false
endpoints.shutdown.enabled=false
endpoints.trace.enabled=false
endpoints.trace.enabled=false
##############################################
# 百度统计 Key
# https://tongji.baidu.com/
# 汇总使用情况登录打开页面etc.
# 登录 -> 管理 -> 新增网站 -> 代码获取 -> 拷贝SiteKey
# hm.src = "https://hm.baidu.com/hm.js?YOUR_SITE_KEY";
# 加入后在百度统计内点击:代码安装检查,代码检查成功表示安装成功;注意网站域名等一致,数据收集有延迟。
##############################################
tongji.baidu.sitekey=

View File

@ -70,7 +70,7 @@ html { *overflow:auto; font-family:"Microsoft Yahei","Helvetica","Simsun","Arial
background-repeat: no-repeat;
background-position: 50%;
background-size: 100%;
padding: 20px 0;
padding: 0 0;
position: relative;
}
.login-box-body, .register-box-body{

View File

@ -7,15 +7,15 @@ $(document).ready(function(){
var protocol = window.location.protocol.replace(/:/g,'');
socket = io(protocol+'://'+hostname+':'+port+'/im/agent?orgi='+orgi+"&userid="+userid+"&session="+session+"&admin="+adminuser , {transports: ['websocket'], upgrade: false});
socket.on('connect',function() {
console.log("连接初始化成功");
console.log("[IM] 连接初始化成功");
//请求服务端记录 当前用户在线事件
}).on('disconnect',function() {
console.log("连接已断开");
console.log("[IM] 连接已断开");
//请求服务端记录,当前用户离线
});
socket.on('chatevent', function(data) {
console.log(data.messageType + " ..... message:"+data.message);
// console.log(data.messageType + " ..... message:"+data.message);
}).on('task', function(data) {
}).on('new', function(data) {
@ -151,8 +151,8 @@ var WebIM = {
});
},
ping : function(){
loadURL("/message/ping.html") ;
console.log("ping:" + new Date().getTime());
loadURL("/message/ping.html") ;
console.log("[IM] heartbeat: " + new Date().getTime())
},
audioplayer:function(id, file, loop) {
var audioplayer = document.getElementById(id);

View File

@ -382,14 +382,24 @@ var Proxy = {
if(result.data.length>0){
type == "agent" ? $("#quickReplyBox").html("") : $("#ccaQuickReplyBox").html("") ;
$.each(sortByKey(result.data,'score'),function(i,n){
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
type == "agent" ? $("#quickReplyBox").append(li) : $("#ccaQuickReplyBox").append(li) ;
var answerList = result.data[i].replies;
var answer;
for(var i = 0; i < answerList.length; i++) {
if(answerList[i].rtype == 'plain' && answerList[i].enabled==true) {
answer=answerList[i]
break;
}
}
if(answer) {
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\'' + answer.content + '\')">\n' +
' <div class="nowrap" title="' + result.data[i].post + '">问题:' + result.data[i].post + '</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="' + answer.content + '" style="float: left ">答案:' + answer.content + '</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\'' + answer.content + '\')">选择</button>\n' +
' </div>\n' +
' </li>'
type == "agent" ? $("#quickReplyBox").append(li) : $("#ccaQuickReplyBox").append(li);
}
if(i>4){
return false;
}

View File

@ -1,10 +1,11 @@
<!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"/>
<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) -->
@ -29,34 +30,47 @@
</style>
</head>
<body>
<h2>全渠道智能客服演示客户端</h2>
<h2>全渠道智能客服演示客户端</h2>
<h3>设置网站渠道</h3>
以管理员身份
<a href="/" target="_blank">登录</a
>,导航【系统-客服接入-网站列表-创建新网站】,按照如下内容设置网站渠道。
<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>
<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>
然后,刷新本页面,就可以在右下角看到【在线客服】聊天控件。
<script>
</script>
然后,刷新本页面,就可以在右下角看到【在线客服】聊天控件。
<br><br><br>
<h2>寻找开发者</h2>
<p>寻找开发者合作智能客服项目,社区共建,携手共赢!</p>
<ul>
<li>组织或个人,在春松客服主页展示为认证开发者</li>
<li>春松客服官方推荐项目机会</li>
<li>专访并通过官方渠道曝光</li>
</ul>
<p>填写申请:<a href="https://www.wjx.top/jq/93397428.aspx" rel="nofollow">https://www.wjx.top/jq/93397428.aspx</a></p>
<script>
</script>
</body>
</html>
</html>

View File

@ -90,11 +90,11 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
});
});
});
KindEditor.lang({
evaluation :'满意度评价'
});
KindEditor.ready(function(K) {
editor = K.create('#message', {
height:"160px",
@ -184,18 +184,29 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
textMessage:editor.html()
}
}).then(function(result){
console.log(result)
if(result.rc === 0){
if(result.data.length > 0){
$("#quickReplyAgentBox").html("");
$.each(sortByKey(result.data,'score'),function(i,n){
var li = ' <li class="ukefu-agentservice-list" style="font-size: 14px;line-height:22px" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p title="'+result.data[i].reply_plain_text+'" class="nowrap" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#quickReplyAgentBox").append(li);
var answerList = result.data[i].replies;
var answer;
for(var i = 0; i < answerList.length; i++) {
if(answerList[i].rtype == 'plain' && answerList[i].enabled==true) {
answer=answerList[i]
break;
}
}
if(answer){
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+answer.content+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="'+answer.content+'" style="float: left ">答案:'+answer.content+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+answer.content+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#quickReplyAgentBox").append(li);
}
if(i>4){
return false;
}
@ -628,14 +639,24 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
if(result.data.length>0){
$("#quickReplyBox").html("");
$.each(sortByKey(result.data,'score'),function(i,n){
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#quickReplyBox").append(li);
var answerList = result.data[i].replies;
var answer;
for(var i = 0; i < answerList.length; i++) {
if(answerList[i].rtype == 'plain' && answerList[i].enabled==true) {
answer=answerList[i]
break;
}
}
if(answer) {
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\'' + answer.content + '\')">\n' +
' <div class="nowrap" title="' + result.data[i].post + '">问题:' + result.data[i].post + '</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="' + answer.content + '" style="float: left ">答案:' + answer.content + '</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\'' + answer.content + '\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#quickReplyBox").append(li);
}
if (i>4){
return false;
}

View File

@ -172,15 +172,25 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
if(result.rc === 0){
if(result.data.length > 0){
$("#ccaQuickReplyAgentBox").html("");
$.each(sortByKey(result.data,'score'),function(i,n){
var li = ' <li class="ukefu-agentservice-list" style="font-size: 14px;line-height:22px" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p title="'+result.data[i].reply_plain_text+'" class="nowrap" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#ccaQuickReplyAgentBox").append(li);
$.each(sortByKey(result.data,'score'),function(i,n){
var answerList = result.data[i].replies;
var answer;
for(var i = 0; i < answerList.length; i++) {
if(answerList[i].rtype == 'plain' && answerList[i].enabled==true) {
answer=answerList[i]
break;
}
}
if(answer) {
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\'' + answer.content + '\')">\n' +
' <div class="nowrap" title="' + result.data[i].post + '">问题:' + result.data[i].post + '</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="' + answer.content + '" style="float: left ">答案:' + answer.content + '</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\'' + answer.content + '\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#ccaQuickReplyAgentBox").append(li);
}
if(i>4){
return false;
}
@ -613,14 +623,24 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
if(result.data.length>0){
$("#ccaQuickReplyBox").html("");
$.each(sortByKey(result.data,'score'),function(i,n){
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#ccaQuickReplyBox").append(li);
var answerList = result.data[i].replies;
var answer;
for(var i = 0; i < answerList.length; i++) {
if(answerList[i].rtype == 'plain' && answerList[i].enabled==true) {
answer=answerList[i]
break;
}
}
if(answer) {
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\'' + answer.content + '\')">\n' +
' <div class="nowrap" title="' + result.data[i].post + '">问题:' + result.data[i].post + '</div>\n' +
' <div style="color: #333">\n' +
' <p class="nowrap" title="' + answer.content + '" style="float: left ">答案:' + answer.content + '</p>\n' +
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\'' + answer.content + '\')">选择</button>\n' +
' </div>\n' +
' </li>'
$("#ccaQuickReplyBox").append(li);
}
if (i>4){
return false;
}

View File

@ -268,7 +268,7 @@ var cskefu = {
<#if inviteData.consult_skill_numbers == 0 || skill_index lt inviteData.consult_skill_numbers >
<#assign skillNum = 0 >
<#list agentList as agent>
<#if agent.organ?? && agent.organ == skill.id>
<#if agent.skills?? && agent.skills[skill.id]??>
<#assign skillNum = skillNum+1 >
</#if>
</#list>

View File

@ -143,6 +143,15 @@
}
}
<#if tongjiBaiduSiteKey??>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?${tongjiBaiduSiteKey}";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</#if>
</script>
</head>
@ -197,9 +206,9 @@
<#if user??>${user.uname!''}<#if tenant??&&tenant.tenantname??>${tenant.tenantname!''}</#if></#if></span></a>
<dl class="layui-nav-child">
<dd><a href="/apps/profile.html" data-toggle="ajax" data-width="750" data-title="修改资料">个人资料</a></dd>
<dd><a href="javascript:void(0)" onclick="quitSystem()" >退出系统</a></dd>
<dd><a href="javascript:void(0)" onclick="showSystemBuildInfo()">关于产品</a></dd>
</dl>
<dd><a href="javascript:void(0)" onclick="quitSystem()" >退出系统</a></dd>
</dl>
</li>
</ul>
</div>
@ -394,11 +403,8 @@
<script>
// 展示系统构建信息
function showSystemBuildInfo(){
console.log("showSystemBuildInfo")
layer.confirm('<div style="text-align:center;"> <img src="/images/favicon.ico" width="50px" height="50px"><p>春松客服<span>&#174;</span></p></div> Release: ${appVersionNumber} <br> Build: ${appBuildDate}.${appVersionAbbrev} <br> Copyright (2018-2019) <a href="https://www.chatopera.com" target="_blank">北京华夏春松科技有限公司</a> <br> Business License applied to ${appCustomerEntity}',
layer.confirm('<div style="text-align:center;"> <img src="/images/favicon.ico" width="50px" height="50px"><p>春松客服<span>&#174;</span></p></div> Release: ${appVersionNumber} <a href="https://docs.chatopera.com/products/cskefu/index.html" target="_blank">文档中心</a> <br> Build: ${appBuildDate}.${appVersionAbbrev} <br> Copyright (2018-2020) <a href="https://www.chatopera.com" target="_blank">北京华夏春松科技有限公司</a> <br> Business License applied to ${appCustomerEntity} <br> <a href="https://docs.chatopera.com/products/cskefu/index.html#%E5%95%86%E4%B8%9A%E6%94%AF%E6%8C%81" target="_blank">购买春松客服企业版或服务</a>',
{icon: -1, title:'关于产品', btn:["关闭"]}, function(index, layero){
//do something
console.log("close showSystemBuildInfo");
layer.close(index);
});
}
@ -446,6 +452,9 @@
}
});
});
console.log("新的转机和闪闪星斗/正在缀满没有遮拦的天空\n春松客服开源的智能客服系统 https://github.com/chatopera/cosin")
</script>
</body>

View File

@ -1,7 +1,5 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
@ -14,6 +12,7 @@
<link rel="stylesheet" href="/css/login.css">
<link rel="stylesheet" href="/css/flexboxgrid.min.css">
<script src="/layui.js"></script>
<script language="javascript">
if((window.frameElement && window.frameElement.id || '') != ""){
top.location.href = "/login.html" ;
@ -42,13 +41,24 @@
document.getElementById("username").value = uid;
}
}
<#if tongjiBaiduSiteKey??>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?${tongjiBaiduSiteKey}";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</#if>
</script>
</head>
<body class="login">
<div class="login-box">
<#if adsLoginBanner??>
<div style="width: 100%; height:50px; background-color: #2bd99e; padding-top: 0px;display: flex;"> <p style="color: white;margin: auto; font-size: 15px">商务洽谈:(+86)136-9149-0568; 售后技术支持:(+86)158-0121-3126; 云服务发票等info@chatopera.com *本提示仅出现于演示环境</p> </div>
</#if>
<div class="login-box">
<div class="login-logo">
<a> <img src="<#if systemConfig?? && systemConfig.loginlogo?? && systemConfig.loginlogo != ''>/res/image.html?id=${systemConfig.loginlogo?url}<#else>images/logo2.png</#if>" style="height:60px;width:220px;">
</a>

View File

@ -12,7 +12,7 @@ JDKNAME=java-1.8.0-amazon-corretto-jdk.deb
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
apt-get update && apt-get install -y --no-install-recommends publicsuffix ca-certificates wget java-common
cd /tmp
wget --no-check-certificate -O $JDKNAME https://d3pxv6yz143wms.cloudfront.net/8.212.04.2/java-1.8.0-amazon-corretto-jdk_8.212.04-2_amd64.deb
wget --no-check-certificate -O $JDKNAME https://static-public.chatopera.com/vendors/java/java-1.8.0-amazon-corretto-jdk_8.212.04-2_amd64.deb
dpkg --install $JDKNAME
rm -rf $JDKNAME
java -version

View File

@ -51,6 +51,8 @@ services:
- BOT_THRESHOLD_FAQ_BEST_REPLY=${BOT_THRESHOLD_FAQ_BEST_REPLY:-0.9}
- BOT_THRESHOLD_FAQ_SUGG_REPLY=${BOT_THRESHOLD_FAQ_SUGG_REPLY:-0.3}
- CSKEFU_SETTINGS_WEBIM_VISITOR_SEPARATE=false
- TONGJI_BAIDU_SITEKEY=${TONGJI_BAIDU_SITEKEY:-placeholder}
- ADS_LOGIN_BANNER=${ADS_LOGIN_BANNER:-off}
depends_on:
- mysql
- redis

View File

@ -59,10 +59,10 @@ public class ChatbotEventSubscription {
ChatbotConstants.BOT_PROVIDER, ChatbotConstants.DEFAULT_BOT_PROVIDER);
// FAQ最佳回复阀值
private final static double thresholdFaqBestReply = Double.parseDouble(SystemEnvHelper.getenv(
private final static double faqBestReplyThreshold = Double.parseDouble(SystemEnvHelper.getenv(
ChatbotConstants.THRESHOLD_FAQ_BEST_REPLY, "0.8"));
// FAQ建议回复阀值
private final static double thresholdFaqSuggReply = Double.parseDouble(SystemEnvHelper.getenv(
private final static double faqSuggReplyThreshold = Double.parseDouble(SystemEnvHelper.getenv(
ChatbotConstants.THRESHOLD_FAQ_SUGG_REPLY, "0.6"));
@Autowired
@ -98,7 +98,7 @@ public class ChatbotEventSubscription {
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
c.getClientId(), c.getSecret(), botServiecProvider);
JSONObject result = bot.conversation(
request.getUserid(), request.getMessage(), thresholdFaqBestReply, thresholdFaqSuggReply);
request.getUserid(), request.getMessage(), faqBestReplyThreshold, faqSuggReplyThreshold);
// parse response
if (result != null) {

View File

@ -12,4 +12,6 @@ ACTIVEMQ_PORT3=8053
DB_PASSWD=123456
LOG_LEVEL=INFO
BOT_THRESHOLD_FAQ_BEST_REPLY=0.8
BOT_THRESHOLD_FAQ_SUGG_REPLY=0.6
BOT_THRESHOLD_FAQ_SUGG_REPLY=0.6
TONGJI_BAIDU_SITEKEY=placeholder
ADS_LOGIN_BANNER=off