mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-01 16:38:02 +08:00
commit
3990a86c9e
134
README.md
134
README.md
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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()) ;
|
||||
|
@ -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()) ;
|
||||
|
@ -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()) ;
|
||||
|
@ -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") ;
|
||||
|
||||
|
@ -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") ;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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=
|
@ -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{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>®</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>®</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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user