Нет описания

WebSocket.java 39KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. package api.service.websocket;
  2. import api.entity.database.online.AutoReply;
  3. import api.entity.database.online.Message;
  4. import api.entity.database.system.Customer;
  5. import api.entity.input.online.MessageInput;
  6. import api.entity.view.online.MessageView;
  7. import api.service.online.IAutoReplyService;
  8. import api.service.online.IMessageService;
  9. import api.service.system.IConfigService;
  10. import api.service.system.ICustomerService;
  11. import api.util.helper.*;
  12. import com.alibaba.fastjson2.JSON;
  13. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  14. import lombok.extern.slf4j.Slf4j;
  15. import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
  16. import me.chanjar.weixin.common.error.WxErrorException;
  17. import me.chanjar.weixin.mp.api.WxMpService;
  18. import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Component;
  21. import javax.annotation.PostConstruct;
  22. import javax.websocket.*;
  23. import javax.websocket.server.PathParam;
  24. import javax.websocket.server.ServerEndpoint;
  25. import java.io.*;
  26. import java.text.ParseException;
  27. import java.text.SimpleDateFormat;
  28. import java.util.*;
  29. import java.util.concurrent.ConcurrentHashMap;
  30. @Slf4j
  31. @Component
  32. @ServerEndpoint("/ws/{source}/{userCode}")
  33. public class WebSocket {
  34. @Autowired
  35. private IMessageService messageService;
  36. @Autowired
  37. private ICustomerService customerService;
  38. @Autowired
  39. private IAutoReplyService autoReplyService;
  40. @Autowired
  41. private IConfigService configService;
  42. @Autowired
  43. private WxMpService wxMpService;
  44. private static WebSocket webSocket;
  45. @PostConstruct
  46. public void init() {
  47. webSocket = this;
  48. }
  49. private Session session;
  50. private Integer source;
  51. private String userCode;
  52. private static Queue<String> servicerQueue = new LinkedList<>();
  53. private static ConcurrentHashMap<String, Session> kfsessionPool = new ConcurrentHashMap<>();
  54. private static ConcurrentHashMap<String, Session> khsessionPool = new ConcurrentHashMap<>();
  55. private static Map<String, Integer> servicers = new HashMap<>();
  56. private static Map<String, Integer> customers = new HashMap<>();
  57. private static Map<String, String> khkfs = new HashMap<>();
  58. /**
  59. * 链接成功调用的方法
  60. */
  61. @OnOpen
  62. public void onOpen(Session session, @PathParam(value = "source") Integer source, @PathParam(value = "userCode") String userCode) {
  63. try {
  64. this.session = session;
  65. this.source = source;
  66. this.userCode = userCode;
  67. boolean reply;
  68. if (source == 1) {
  69. reply=servicers.containsKey(userCode);
  70. if(!reply) {
  71. kfsessionPool.put(userCode, session);
  72. servicers.put(userCode, 1);
  73. servicerQueue.add(userCode);
  74. }
  75. } else {
  76. reply = customers.containsKey(userCode);
  77. if (!reply) {
  78. customers.put(userCode, source);
  79. khsessionPool.put(userCode, session);
  80. Long pid = null;
  81. List<String> ps = session.getRequestParameterMap().get("project");
  82. if (!ps.isEmpty()) pid = Long.valueOf(ps.get(0));
  83. addCustomer(userCode, source, pid);
  84. String first= webSocket.configService.getConfigValue("AutoReply");
  85. if(StringHelper.isNotEmpty(first)){
  86. MessageView mv = new MessageView();
  87. mv.setStatus("success");
  88. mv.setType("text");
  89. mv.setContent(first);
  90. sendText(session,JSON.toJSONString(mv));
  91. Message msg1 = new Message();
  92. msg1.setCreateTime(new Date());
  93. msg1.setStatus(0);
  94. msg1.setSend(2);
  95. msg1.setKhUser(userCode);
  96. msg1.setKhSource(source);
  97. msg1.setKfUser("System");
  98. msg1.setMsgType("text");
  99. msg1.setMsgContent(first);
  100. AsyncHelper.instance().execute(new TimerTask() {
  101. @Override
  102. public void run() {
  103. webSocket.messageService.insert(msg1);
  104. }
  105. });
  106. }
  107. }
  108. }
  109. if(reply) {
  110. MessageView mv1 = new MessageView();
  111. mv1.setStatus("error");
  112. mv1.setContent("签入失败,重复签入");
  113. sendText(session,JSON.toJSONString(mv1));
  114. session.close();
  115. }
  116. } catch (Exception e) {
  117. log.error("open错误", e);
  118. }
  119. }
  120. /**
  121. * 链接关闭调用的方法
  122. */
  123. @OnClose
  124. public void onClose() {
  125. try {
  126. if (source == 1) {
  127. kfsessionPool.remove(userCode);
  128. servicerQueue.remove(userCode);
  129. servicers.remove(userCode);
  130. if(khkfs.values().contains(userCode)) {
  131. khkfs.values().removeIf(p -> p.equals(userCode));
  132. }
  133. } else {
  134. customers.remove(userCode);
  135. String kf = khkfs.get(userCode);
  136. if (!StringHelper.isEmpty(kf)) {
  137. Session session1 = kfsessionPool.get(kf);
  138. if (session1 != null) {
  139. MessageView mv1 = new MessageView();
  140. mv1.setStatus("error");
  141. mv1.setContent("客户已下线");
  142. mv1.setUser(userCode);
  143. sendText(session1,JSON.toJSONString(mv1));
  144. }
  145. khsessionPool.remove(userCode);
  146. khkfs.remove(userCode);
  147. }
  148. }
  149. } catch (Exception e) {
  150. log.error("close错误", e);
  151. }
  152. }
  153. /**
  154. * 收到客户端消息后调用的方法
  155. *
  156. * @param message
  157. */
  158. @OnMessage
  159. public void onMessage(String message) {
  160. MessageInput mv = JSON.parseObject(message, MessageInput.class);
  161. if (mv != null) {
  162. String type = mv.getType();
  163. if (type.equals("heart")) {
  164. MessageView mvh = new MessageView();
  165. mvh.setStatus("success");
  166. mvh.setType(type);
  167. mvh.setContent(mv.getContent());
  168. sendText(session,JSON.toJSONString(mvh));
  169. return;
  170. }
  171. List<Message> messages = new ArrayList<>();
  172. String content = mv.getContent();
  173. Message msg = new Message();
  174. msg.setCreateTime(new Date());
  175. msg.setStatus(0);
  176. msg.setMsgType(type);
  177. if ("text".equals(type)) {
  178. msg.setMsgContent(content);
  179. }
  180. if ("image".equals(type)) {
  181. msg.setMsgFile(content);
  182. }
  183. //客服发送消息
  184. if (this.source == 1) {
  185. msg.setSend(2);
  186. msg.setKfUser(userCode);
  187. String kh = mv.getUser();
  188. boolean exist = false;
  189. MessageView mv1 = new MessageView();
  190. mv1.setUser(userCode);
  191. String en = khExist(userCode, kh);
  192. if (StringHelper.isEmpty(en)) {
  193. exist = true;
  194. msg.setKhUser(kh);
  195. Integer toSource = customers.get(kh);
  196. msg.setKhSource(toSource);
  197. //微信客户
  198. if (toSource == 2) {
  199. try {
  200. WxMpKefuMessage wechatMessage = WxMpKefuMessage.TEXT().toUser(kh).content(content).build();
  201. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  202. } catch (WxErrorException e) {
  203. log.error("发送微信消息失败", e);
  204. mv1.setStatus("error");
  205. mv1.setContent("发送微信消息失败");
  206. sendText(session,JSON.toJSONString(mv1));
  207. return;
  208. }
  209. } else {
  210. //其他客户
  211. Session session1 = khsessionPool.get(kh);
  212. mv1.setStatus("success");
  213. mv1.setType(type);
  214. mv1.setContent(content);
  215. sendText(session1,JSON.toJSONString(mv1));
  216. }
  217. } else {
  218. mv1.setStatus("error");
  219. mv1.setContent(en);
  220. }
  221. if (!exist) {
  222. sendText(session,JSON.toJSONString(mv1));
  223. return;
  224. }
  225. } else {
  226. //客户发送消息
  227. msg.setSend(1);
  228. msg.setKhUser(userCode);
  229. msg.setKhSource(source);
  230. String kf = khkfs.get(userCode);
  231. boolean zrg = false;
  232. if (StringHelper.isEmpty(kf)) {
  233. String first = webSocket.configService.getConfigValue("AutoReply");
  234. if (StringHelper.isNotEmpty(first)) {//自动回复
  235. if ("text".equals(type)) {
  236. String[] keys = new String[]{"人工", "客服"};
  237. if (!StringHelper.containList(content, keys)) {
  238. //if (!content.contains("人工")) {
  239. //获取匹配的记录
  240. AutoReply[] list = webSocket.autoReplyService.selectMatchList(1, content);
  241. if (list != null && list.length > 0) {
  242. msg.setKfUser("System");
  243. AutoReply ar = list[0];
  244. LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper();
  245. qw.eq(Message::getReplyId, ar.getAutoreplyId());
  246. qw.eq(Message::getKhUser, userCode);
  247. try {
  248. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  249. qw.ge(Message::getCreateTime, sdf.parse(sdf.format(new Date())));
  250. } catch (ParseException e) {
  251. throw new RuntimeException(e);
  252. }
  253. long n = webSocket.messageService.getCount(qw);//当天回复次数
  254. if (ar.getReplyCount() == 0 || (ar.getReplyCount() > 0 && n < ar.getReplyCount())) {
  255. //回复内容条数
  256. List<Map<String, Object>> cs = ar.getContent();
  257. if (cs != null && cs.size() > 0) {
  258. Message msg1 = new Message();
  259. msg1.setCreateTime(new Date());
  260. msg1.setStatus(0);
  261. msg1.setSend(2);
  262. msg1.setKhUser(userCode);
  263. msg1.setKhSource(source);
  264. msg1.setKfUser("System");
  265. msg1.setReplyId(ar.getAutoreplyId());
  266. if (ar.getReplyType() == 3) {//全部回复
  267. for (Map<String, Object> c : cs) {
  268. String hftype = c.get("type").toString();
  269. String hfcontent = c.get("content").toString();
  270. Message msg2 = JSON.parseObject(JSON.toJSONString(msg1), Message.class);
  271. msg2.setMsgType(hftype);
  272. if ("text".equals(hftype)) {
  273. msg2.setMsgContent(hfcontent);
  274. }
  275. if ("image".equals(hftype)) {
  276. msg2.setMsgFile(hfcontent);
  277. }
  278. messages.add(msg2);
  279. MessageView mv1 = new MessageView();
  280. mv1.setStatus("success");
  281. mv1.setType(hftype);
  282. mv1.setContent(hfcontent);
  283. sendText(session,JSON.toJSONString(mv1));
  284. }
  285. } else {
  286. int rn = cs.size();
  287. String hftype = cs.get(0).get("type").toString();
  288. String hfcontent = cs.get(0).get("content").toString();
  289. if (rn > 1) {
  290. int number = 0;
  291. if (ar.getReplyType() == 1) {//随机一条
  292. number = new Random().nextInt(rn);
  293. } else if (ar.getReplyType() == 2) {//顺序一条
  294. number = (int) (n % rn);
  295. }
  296. hftype = cs.get(number).get("type").toString();
  297. hfcontent = cs.get(number).get("content").toString();
  298. }
  299. msg1.setMsgType(hftype);
  300. if ("text".equals(hftype)) {
  301. msg1.setMsgContent(hfcontent);
  302. }
  303. if ("image".equals(hftype)) {
  304. msg1.setMsgFile(hfcontent);
  305. }
  306. messages.add(msg1);
  307. MessageView mv1 = new MessageView();
  308. mv1.setStatus("success");
  309. mv1.setType(hftype);
  310. mv1.setContent(hfcontent);
  311. sendText(session,JSON.toJSONString(mv1));
  312. }
  313. }
  314. }
  315. }
  316. } else {//转人工
  317. zrg = true;
  318. }
  319. }
  320. } else {
  321. zrg = true;
  322. }
  323. if (zrg) {
  324. MessageView mv1 = new MessageView();
  325. mv1.setStatus("success");
  326. mv1.setType("text");
  327. mv1.setContent("人工客服正火速赶来,请稍等...");
  328. sendText(session,JSON.toJSONString(mv1));
  329. mv1.setContent("【人工客服工作时间为每天(含节假日)8:30-20:00,如现在非工作时间,建议您使用自助服务或者在工作时间联系我们。】");
  330. sendText(session,JSON.toJSONString(mv1));
  331. mv1.setContent("正在接入客服,请稍后...");
  332. sendText(session,JSON.toJSONString(mv1));
  333. }
  334. } else if (servicers.get(kf) == 2) {//客服置忙
  335. zrg = true;
  336. }
  337. if (zrg) {
  338. kf = servicerQueue.poll();
  339. if (!StringHelper.isEmpty(kf)) {
  340. servicerQueue.add(kf);
  341. khkfs.put(userCode, kf);
  342. }
  343. }
  344. if (!StringHelper.isEmpty(kf)) {
  345. Session session1 = kfsessionPool.get(kf);
  346. if (session1 != null) {
  347. msg.setKfUser(kf);
  348. MessageView mv1 = new MessageView();
  349. mv1.setStatus("success");
  350. mv1.setType(type);
  351. mv1.setContent(content);
  352. mv1.setUser(userCode);
  353. sendText(session1,JSON.toJSONString(mv1));
  354. }
  355. }
  356. }
  357. //webSocket.messageService.insert(msg);
  358. AsyncHelper.instance().execute(new TimerTask() {
  359. @Override
  360. public void run() {
  361. messages.add(0, msg);
  362. webSocket.messageService.insert(messages);
  363. }
  364. });
  365. }
  366. }
  367. /**
  368. * 发送错误时的处理
  369. *
  370. * @param error
  371. */
  372. @OnError
  373. public void onError(Throwable error) {
  374. if (source == 1) {
  375. kfsessionPool.remove(userCode);
  376. servicerQueue.remove(userCode);
  377. servicers.remove(userCode);
  378. if(khkfs.values().contains(userCode)) {
  379. khkfs.values().removeIf(p -> p.equals(userCode));
  380. }
  381. } else {
  382. customers.remove(userCode);
  383. String kf = khkfs.get(userCode);
  384. if (!StringHelper.isEmpty(kf)) {
  385. Session session1 = kfsessionPool.get(kf);
  386. if (session1 != null) {
  387. MessageView mv1 = new MessageView();
  388. mv1.setStatus("error");
  389. mv1.setContent("客户已下线");
  390. mv1.setUser(userCode);
  391. sendText(session1,JSON.toJSONString(mv1));
  392. }
  393. khsessionPool.remove(userCode);
  394. khkfs.remove(userCode);
  395. }
  396. }
  397. error.printStackTrace();
  398. }
  399. //发送消息处理
  400. private void sendText(Session s,String msg){
  401. if (s != null && s.isOpen()) {
  402. synchronized (s) {
  403. try {
  404. s.getBasicRemote().sendText(msg);
  405. } catch (IOException e) {
  406. log.error(msg+" 发送失败",e);
  407. if(e.getMessage().contains("close")) {
  408. try {
  409. s.close();
  410. } catch (IOException ex) {
  411. log.error(msg + " 关闭失败", ex);
  412. }
  413. }
  414. }
  415. }
  416. }
  417. }
  418. //客户转移
  419. public String khTransfer(String kf,String kh) {
  420. String msg = "客户已下线";
  421. if(!(servicers.containsKey(kf)&&kfsessionPool.containsKey(kf))){
  422. msg = "此客服未签入";
  423. } else if(servicers.get(kf)==2) {
  424. msg = "此客服忙碌";
  425. } else if (!StringHelper.isEmpty(kh)) {
  426. if (customers.containsKey(kh)) {
  427. if (khkfs.containsKey(kh)) {
  428. if (khkfs.get(kh).equals(kf) ) {
  429. msg = "不能转移给自己";
  430. } else {
  431. khkfs.replace(kh,kf);
  432. msg = "";
  433. }
  434. } else {
  435. if (customers.get(kh) == 2||khsessionPool.containsKey(kh)) {
  436. khkfs.put(kh, kf);
  437. msg = "";
  438. }
  439. }
  440. } else {
  441. LambdaQueryWrapper<Customer> qw = new LambdaQueryWrapper();
  442. qw.eq(Customer::getCustomerNo, kh).eq(Customer::getType,2);
  443. if (webSocket.customerService.exists(qw)) {
  444. Date sj=new Date(new Date().getTime()-(1000*60*60*48));
  445. LambdaQueryWrapper<Message> qw1 = new LambdaQueryWrapper();
  446. qw1.eq(Message::getKhUser,kh).eq(Message::getSend,2).gt(Message::getCreateTime,sj);
  447. if(webSocket.messageService.exists(qw1)) {
  448. customers.put(kh, 2);
  449. khkfs.put(kh, kf);
  450. msg = "";
  451. }
  452. }
  453. }
  454. } else {
  455. msg = "客户不能为空";
  456. }
  457. if(StringHelper.isEmpty(msg)){
  458. Session session1=kfsessionPool.get(kf);
  459. MessageView mv1 = new MessageView();
  460. mv1.setStatus("success");
  461. mv1.setType("transfer");
  462. mv1.setContent("转移客户");
  463. mv1.setUser(kh);
  464. sendText(session1,JSON.toJSONString(mv1));
  465. }
  466. return msg;
  467. }
  468. //客户是否存在
  469. public String khExist(String kf,String kh) {
  470. String msg = "客户已下线";
  471. if(!(servicers.containsKey(kf)&&kfsessionPool.containsKey(kf))){
  472. msg = "未签入";
  473. }
  474. else if (!StringHelper.isEmpty(kh)) {
  475. if (customers.containsKey(kh)) {
  476. if (khkfs.containsKey(kh)) {
  477. if (khkfs.get(kh).equals(kf) ) {
  478. if (customers.get(kh) == 2) {
  479. msg = "";
  480. } else {
  481. if (khsessionPool.containsKey(kh)) {
  482. msg = "";
  483. }
  484. }
  485. } else {
  486. msg = "其他客服已接入";
  487. }
  488. } else {
  489. if (customers.get(kh) == 2||khsessionPool.containsKey(kh)) {
  490. khkfs.put(kh, kf);
  491. msg = "";
  492. }
  493. }
  494. } else {
  495. LambdaQueryWrapper<Customer> qw = new LambdaQueryWrapper();
  496. qw.eq(Customer::getCustomerNo, kh).eq(Customer::getType,2);
  497. if (webSocket.customerService.exists(qw)) {
  498. Date sj=new Date(new Date().getTime()-(1000*60*60*48));
  499. LambdaQueryWrapper<Message> qw1 = new LambdaQueryWrapper();
  500. qw1.eq(Message::getKhUser,kh).eq(Message::getSend,1).gt(Message::getCreateTime,sj);
  501. if(webSocket.messageService.exists(qw1)) {
  502. customers.put(kh, 2);
  503. khkfs.put(kh, kf);
  504. msg = "";
  505. }
  506. }
  507. }
  508. } else {
  509. msg = "客户不能为空";
  510. }
  511. return msg;
  512. }
  513. //客服发送图片消息
  514. public void kfSendImageMessage(MessageInput mv,String kf) {
  515. String type = mv.getType();
  516. String content = mv.getContent();
  517. String kh = mv.getUser();
  518. Message message = new Message();
  519. message.setStatus(0);
  520. message.setMsgType(type);
  521. message.setMsgFile(content);
  522. message.setKhUser(kh);
  523. message.setSend(2);
  524. message.setCreateTime(new Date());
  525. message.setKfUser(kf);
  526. Integer source = customers.get(kh);
  527. message.setKhSource(source);
  528. //发送给微信客户
  529. if (source == 2) {
  530. try {
  531. File file = new File(content);
  532. if (file.exists()) {
  533. WxMediaUploadResult result = webSocket.wxMpService.getMaterialService().mediaUpload(type, file);
  534. String MediaId = result.getMediaId();
  535. WxMpKefuMessage wechatMessage = WxMpKefuMessage.IMAGE().toUser(kh).mediaId(MediaId).build();
  536. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  537. message.setMsgMediaid(MediaId);
  538. }
  539. } catch (WxErrorException e) {
  540. log.error("上传文件失败", e);
  541. throw new RuntimeException(e);
  542. }
  543. } else {
  544. //发送其他客户
  545. MessageView mv1 = new MessageView();
  546. mv1.setStatus("success");
  547. mv1.setType(type);
  548. mv1.setContent(content);
  549. sendText(khsessionPool.get(kh),JSON.toJSONString(mv1));
  550. }
  551. webSocket.messageService.insert(message);
  552. }
  553. // 微信信息转发给客服
  554. public void toWxMessage(Map<String, String> map) {
  555. String sendUser = map.get("FromUserName");
  556. String msgType = map.get("MsgType");
  557. List<Message> messages = new ArrayList<>();
  558. Message message = new Message();
  559. message.setSend(1);
  560. message.setKhUser(sendUser);
  561. message.setKhSource(2);
  562. message.setStatus(0);
  563. message.setMsgType(msgType);
  564. message.setCreateTime(new Date());
  565. boolean zrg = false;
  566. String content = "";
  567. if ("text".equals(msgType)) {
  568. content = map.get("Content");
  569. message.setMsgContent(content);
  570. } else if ("image".equals(msgType) || "voice".equals(msgType)) {
  571. String mediaId = map.get("MediaId");
  572. message.setMsgMediaid(mediaId);
  573. String fn = System.currentTimeMillis() + ".";
  574. String fileName = fn + "jpg";
  575. if ("voice".equals(msgType)) {
  576. message.setMsgFormat(map.get("Format"));
  577. fileName = fn + map.get("Format");
  578. }
  579. //下载临时素材
  580. try {
  581. String path = "files/online/" + DateHelper.getDate();
  582. File pFile = new File(path);
  583. if (!pFile.exists()) pFile.mkdirs();
  584. String filePath = pFile.getAbsolutePath() + "/" + fileName;
  585. File lFile = new File(filePath);
  586. if (!lFile.exists()) lFile.createNewFile();
  587. File file = webSocket.wxMpService.getMaterialService().mediaDownload(mediaId);
  588. InputStream inputStream = new FileInputStream(file);
  589. byte[] buffer = new byte[1024];
  590. FileOutputStream outputStream = new FileOutputStream(lFile);
  591. int length;
  592. while ((length = inputStream.read(buffer)) > 0) {
  593. outputStream.write(buffer, 0, length);
  594. }
  595. inputStream.close();
  596. outputStream.close();
  597. message.setMsgFile(path + "/" + fileName);
  598. content = path + "/" + fileName;
  599. } catch (WxErrorException e) {
  600. log.error("下载文件失败", e);
  601. throw new RuntimeException(e);
  602. } catch (IOException e) {
  603. log.error("下载文件失败", e);
  604. throw new RuntimeException(e);
  605. }
  606. } else{
  607. return;
  608. }
  609. if (!customers.containsKey(sendUser)) {
  610. customers.put(sendUser, 2);
  611. addCustomer(sendUser, 2, null);
  612. }
  613. String kf = khkfs.get(sendUser);
  614. // if (StringHelper.isEmpty(kf)||servicers.get(kf)==2) {
  615. // kf = servicerQueue.poll();
  616. // if (!StringHelper.isEmpty(kf)) {
  617. // servicerQueue.add(kf);
  618. // khkfs.put(sendUser, kf);
  619. // }
  620. // }
  621. if (StringHelper.isEmpty(kf)) {
  622. String first = webSocket.configService.getConfigValue("AutoReply");
  623. if (StringHelper.isNotEmpty(first)) {//自动回复
  624. if ("text".equals(msgType)) {
  625. String[] keys = new String[]{"人工", "客服"};
  626. if (!StringHelper.containList(content, keys)) {
  627. //if (!content.contains("人工")) {
  628. //获取匹配的记录
  629. AutoReply[] list = webSocket.autoReplyService.selectMatchList(2, content);
  630. if (list != null && list.length > 0) {
  631. message.setKfUser("System");
  632. AutoReply ar = list[0];
  633. LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper();
  634. qw.eq(Message::getReplyId, ar.getAutoreplyId());
  635. qw.eq(Message::getKhUser, sendUser);
  636. try {
  637. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  638. qw.ge(Message::getCreateTime, sdf.parse(sdf.format(new Date())));
  639. } catch (ParseException e) {
  640. throw new RuntimeException(e);
  641. }
  642. long n = webSocket.messageService.getCount(qw);//当天回复次数
  643. if (ar.getReplyCount()==0||(ar.getReplyCount() > 0 && n < ar.getReplyCount())) {
  644. List<Map<String, Object>> cs = ar.getContent();
  645. if (cs != null && cs.size() > 0) {
  646. Message msg1 = new Message();
  647. msg1.setCreateTime(new Date());
  648. msg1.setStatus(0);
  649. msg1.setSend(2);
  650. msg1.setKhUser(sendUser);
  651. msg1.setKhSource(2);
  652. msg1.setKfUser("System");
  653. msg1.setReplyId(ar.getAutoreplyId());
  654. if (ar.getReplyType() == 3) {//全部回复
  655. for (Map<String, Object> c : cs) {
  656. String hftype = c.get("type").toString();
  657. String hfcontent = c.get("content").toString();
  658. Message msg2 = JSON.parseObject(JSON.toJSONString(msg1), Message.class);
  659. msg2.setMsgType(hftype);
  660. if ("text".equals(hftype)) {
  661. msg2.setMsgContent(hfcontent);
  662. try {
  663. WxMpKefuMessage wechatMessage = WxMpKefuMessage.TEXT().toUser(sendUser).content(hfcontent).build();
  664. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  665. } catch (WxErrorException e) {
  666. throw new RuntimeException(e);
  667. }
  668. }
  669. if ("image".equals(hftype)) {
  670. msg2.setMsgFile(hfcontent);
  671. try {
  672. File file = new File(hfcontent);
  673. if (file.exists()) {
  674. WxMediaUploadResult result = webSocket.wxMpService.getMaterialService().mediaUpload(hftype, file);
  675. String MediaId = result.getMediaId();
  676. WxMpKefuMessage wechatMessage = WxMpKefuMessage.IMAGE().toUser(sendUser).mediaId(MediaId).build();
  677. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  678. msg1.setMsgMediaid(MediaId);
  679. }
  680. } catch (WxErrorException e) {
  681. log.error("上传文件失败", e);
  682. throw new RuntimeException(e);
  683. }
  684. }
  685. messages.add(msg2);
  686. }
  687. } else {
  688. int rn = cs.size();
  689. String hftype = cs.get(0).get("type").toString();
  690. String hfcontent = cs.get(0).get("content").toString();
  691. if (rn > 1) {
  692. int number = 0;
  693. if (ar.getReplyType() == 1) {//随机一条
  694. number = new Random().nextInt(rn);
  695. } else if (ar.getReplyType() == 2) {//顺序一条
  696. number = (int) (n % rn);
  697. }
  698. hftype = cs.get(number).get("type").toString();
  699. hfcontent = cs.get(number).get("content").toString();
  700. }
  701. msg1.setMsgType(hftype);
  702. if ("text".equals(hftype)) {
  703. msg1.setMsgContent(hfcontent);
  704. try {
  705. WxMpKefuMessage wechatMessage = WxMpKefuMessage.TEXT().toUser(sendUser).content(hfcontent).build();
  706. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  707. } catch (WxErrorException e) {
  708. throw new RuntimeException(e);
  709. }
  710. }
  711. if ("image".equals(hftype)) {
  712. msg1.setMsgFile(hfcontent);
  713. try {
  714. File file = new File(hfcontent);
  715. if (file.exists()) {
  716. WxMediaUploadResult result = webSocket.wxMpService.getMaterialService().mediaUpload(hftype, file);
  717. String MediaId = result.getMediaId();
  718. WxMpKefuMessage wechatMessage = WxMpKefuMessage.IMAGE().toUser(sendUser).mediaId(MediaId).build();
  719. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage);
  720. msg1.setMsgMediaid(MediaId);
  721. }
  722. } catch (WxErrorException e) {
  723. log.error("上传文件失败", e);
  724. throw new RuntimeException(e);
  725. }
  726. }
  727. messages.add(msg1);
  728. }
  729. }
  730. }
  731. }
  732. } else {//转人工
  733. zrg = true;
  734. }
  735. }
  736. } else {
  737. zrg = true;
  738. }
  739. if (zrg) {
  740. try {
  741. String ct1="人工客服正火速赶来,请稍等……";
  742. WxMpKefuMessage wechatMessage1 = WxMpKefuMessage.TEXT().toUser(sendUser).content(ct1).build();
  743. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage1);
  744. String ct2="【人工客服工作时间为每天(含节假日)8:30-20:00,如现在非工作时间,建议您使用自助服务或者在工作时间联系我们。】";
  745. WxMpKefuMessage wechatMessage2 = WxMpKefuMessage.TEXT().toUser(sendUser).content(ct2).build();
  746. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage2);
  747. String ct3="正在接入客服,请稍后...";
  748. WxMpKefuMessage wechatMessage3 = WxMpKefuMessage.TEXT().toUser(sendUser).content(ct3).build();
  749. webSocket.wxMpService.getKefuService().sendKefuMessage(wechatMessage3);
  750. } catch (WxErrorException e) {
  751. throw new RuntimeException(e);
  752. }
  753. }
  754. } else if (servicers.get(kf) == 2) {//客服置忙
  755. zrg = true;
  756. }
  757. if (zrg) {//转人工
  758. kf = servicerQueue.poll();
  759. if (!StringHelper.isEmpty(kf)) {
  760. servicerQueue.add(kf);
  761. khkfs.put(sendUser, kf);
  762. }
  763. }
  764. if (!StringHelper.isEmpty(kf)) {
  765. message.setKfUser(kf);
  766. Session session1 = kfsessionPool.get(kf);
  767. if (session1 != null) {
  768. MessageView mv = new MessageView();
  769. mv.setStatus("success");
  770. mv.setType(msgType);
  771. mv.setContent(content);
  772. mv.setUser(sendUser);
  773. sendText(session1,JSON.toJSONString(mv));
  774. }
  775. }
  776. messages.add(0, message);
  777. webSocket.messageService.insert(messages);
  778. }
  779. public void addCustomer(String userCode,Integer source,Long project) {
  780. LambdaQueryWrapper<Customer> qw = new LambdaQueryWrapper();
  781. qw.eq(Customer::getCustomerNo, userCode);
  782. if (!webSocket.customerService.exists(qw)) {
  783. Customer customer = new Customer();
  784. customer.setCustomerNo(userCode);
  785. customer.setType(Long.valueOf(source));
  786. customer.setProject(project);
  787. customer.setFCreatetime(new Date());
  788. customer.setFIsdelete(0L);
  789. webSocket.customerService.insert(customer);
  790. }
  791. }
  792. //客服置忙
  793. public void kfBusy(String userCode) {
  794. if (servicers.containsKey(userCode)) {
  795. servicers.replace(userCode, 2);
  796. }
  797. if (servicerQueue.contains(userCode)) {
  798. servicerQueue.remove(userCode);
  799. }
  800. }
  801. //客服置闲
  802. public void kfFree(String userCode) {
  803. if (servicers.containsKey(userCode)) {
  804. servicers.replace(userCode, 1);
  805. }
  806. if (!servicerQueue.contains(userCode)) {
  807. servicerQueue.add(userCode);
  808. }
  809. }
  810. //获取信息
  811. public Object GetMap(Integer type) {
  812. if (type == 1) {
  813. return servicers;
  814. }
  815. if (type == 2) {
  816. return customers;
  817. }
  818. if (type == 3) {
  819. return khkfs;
  820. }
  821. if (type == 4) {
  822. return servicerQueue;
  823. }
  824. return servicers;
  825. }
  826. }