颐和api

ChatHub.cs 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. using MadRunFabric.Model;
  2. using Microsoft.AspNetCore.SignalR;
  3. using Microsoft.Extensions.Logging;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using OnLineChatApi.IRepositories;
  11. namespace OnLineChatApi.Class
  12. {
  13. public class ChatHub : Hub
  14. {
  15. private readonly ILogger<ChatHub> _logger;
  16. private IChat_UserRepository _chatuserRepository;
  17. private IChat_InOutRepository _chatinoutRepository;
  18. private IChat_MessageRepository _chatmessageRepository;
  19. private IChat_ProcessRepository _chatprocessRepository;
  20. private IChat_SessionRepository _chatsessionRepository;
  21. private ISys_DictionaryValueRepository _sys_dictionaryValuerepository;
  22. public static List<string> ConnectionIds = new List<string>();
  23. public static List<ChatClass.Servicer> Servicers = new List<ChatClass.Servicer>();
  24. public static List<ChatClass.Customer> Customers = new List<ChatClass.Customer>();
  25. private static readonly object lockobj = new object();
  26. public ChatHub(IChat_UserRepository chatuserRepository, IChat_InOutRepository chatinoutRepository, IChat_MessageRepository chatmessageRepository,
  27. IChat_ProcessRepository chatprocessRepository, IChat_SessionRepository chatsessionRepository,
  28. ISys_DictionaryValueRepository sys_dictionaryValuerepository, ILogger<ChatHub> logger)
  29. {
  30. _logger = logger;
  31. _chatuserRepository = chatuserRepository;
  32. _chatinoutRepository = chatinoutRepository;
  33. _chatmessageRepository = chatmessageRepository;
  34. _chatprocessRepository = chatprocessRepository;
  35. _chatsessionRepository = chatsessionRepository;
  36. _sys_dictionaryValuerepository = sys_dictionaryValuerepository;
  37. }
  38. /// <summary>
  39. /// 接收信息
  40. /// </summary>
  41. /// <param name="message"></param>
  42. /// <returns></returns>
  43. public async Task ReceiveMessage(string message)
  44. {
  45. try
  46. {
  47. //_logger.LogError(message);
  48. var ip = getipaddress();
  49. JObject msg = JsonConvert.DeserializeObject<JObject>(message);
  50. msg["state"] = 1;
  51. int channel = msg["channel"] != null ? Int32.Parse(msg["channel"].ToString()) : 0;
  52. switch (msg["action"].ToString().ToLower())
  53. {
  54. case "cusconn":
  55. #region 客户连接
  56. if (msg["usercode"] == null || msg["usercode"].ToString() == "")
  57. {
  58. msg["usercode"] = "web" + DateTime.Now.Ticks;
  59. msg["name"] = "游客";
  60. }
  61. //客户不存在,则创建
  62. var cususer = _chatuserRepository.Get(p => p.usercode == msg["usercode"].ToString()).Result.FirstOrDefault();
  63. if (cususer == null)
  64. {
  65. cususer = new Chat_User();
  66. cususer.usercode = msg["usercode"].ToString();
  67. cususer.name = msg["name"] != null ? msg["name"].ToString() : "";
  68. cususer.headimgurl = msg["headimgurl"] != null ? msg["headimgurl"].ToString() : "";
  69. cususer.ip = new List<string>() { ip };
  70. cususer.type = 1;
  71. cususer.createuser = msg["usercode"].ToString();
  72. cususer.createtime = DateTime.Now;
  73. cususer.isdelete = 0;
  74. await _chatuserRepository.Add(cususer);
  75. }
  76. //新增客户上线记录
  77. Chat_InOut cio = new Chat_InOut();
  78. cio.channel = msg["channel"] != null ? Int32.Parse(msg["channel"].ToString()) : 0;
  79. cio.intime = DateTime.Now;
  80. cio.ip = ip;
  81. cio.connectionid = Context.ConnectionId;
  82. cio.type = 1;
  83. cio.usercode = msg["usercode"].ToString();
  84. cio.name = msg["name"] != null ? msg["name"].ToString() : "";
  85. cio.headimgurl = msg["headimgurl"] != null ? msg["headimgurl"].ToString() : "";
  86. cio.isdelete = 0;
  87. cio.createtime = DateTime.Now;
  88. cio.createuser = msg["usercode"].ToString();
  89. await _chatinoutRepository.Add(cio);
  90. //新增客户会话记录
  91. Chat_Session ses = new Chat_Session();
  92. ses.chatusers = new List<chatuser>();
  93. chatuser cuser = new chatuser();
  94. cuser.connectionid = Context.ConnectionId;
  95. cuser.usercode = cususer.usercode;
  96. cuser.name = cususer.name;
  97. cuser.headimgurl = cususer.headimgurl;
  98. cuser.ip = ip;
  99. cuser.isonline = 1;
  100. cuser.type = 1;
  101. ses.chatusers.Add(cuser);
  102. ses.state = 1;
  103. ses.isdelete = 0;
  104. ses.createtime = DateTime.Now;
  105. ses.type = 1;
  106. ses.step = 1;
  107. ses.sertype = 1;
  108. ses.stepresult = new List<string>();
  109. ses.id = await _chatsessionRepository.AddRetID(ses);
  110. msg["sessionid"] = ses.id;
  111. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  112. await SystemReply(ses);
  113. Customers.Remove(Customers.Where(p => p.UserCode == cususer.usercode).FirstOrDefault());
  114. Customers.Remove(Customers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault());
  115. ChatClass.Customer customer = new ChatClass.Customer();
  116. customer.ConnectionId= Context.ConnectionId;
  117. customer.SessionID = ses.id;
  118. customer.UserCode= cususer.usercode;
  119. Customers.Add(customer);
  120. #endregion
  121. break;
  122. case "cussend":
  123. #region 客户发送消息
  124. var sessionid = msg["sessionid"].ToString();
  125. var cussendsession = _chatsessionRepository.GetSingle(sessionid).Result;
  126. var sessionusers = cussendsession.chatusers;
  127. var conncususer = sessionusers.Where(p => p.connectionid == Context.ConnectionId).FirstOrDefault();
  128. await AddMessage(cussendsession.id, channel, conncususer.usercode, msg["message"].ToString(), new List<string>(), cussendsession.step);
  129. if (cussendsession.sertype == 1)//系统客服
  130. {
  131. #region 系统客服
  132. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  133. bool bl = true;
  134. bool iscomplete = true;
  135. string value = msg["message"].ToString();
  136. var options = new List<string>();
  137. var step = _chatprocessRepository.Get(p => p.isdelete == 0 && p.step == cussendsession.step).Result.FirstOrDefault();
  138. if (step != null)
  139. {
  140. if (step.optiontype == 1)
  141. {
  142. var optionlist = await _sys_dictionaryValuerepository.Get(p => p.dictionarycode == step.dictionarycode && p.statetype == true);
  143. options = optionlist.Select(p => p.name).ToList();
  144. }
  145. if (step.optiontype == 2)
  146. {
  147. options = step.options;
  148. }
  149. if (options.Count() > 0)
  150. {
  151. try
  152. {
  153. int num = Int32.Parse(value);
  154. int count = options.Count;
  155. if (num > count || num < 1)//数字选择验证
  156. {
  157. bl = false;
  158. }
  159. else
  160. {
  161. value = options[num - 1];
  162. }
  163. }
  164. catch
  165. {
  166. if (!options.Contains(value))//文字选择验证
  167. {
  168. bl = false;
  169. }
  170. }
  171. }
  172. if (!bl)
  173. {
  174. iscomplete = false;
  175. string msgcontent = "输入有误,请重新输入";
  176. var cusmsg = new
  177. {
  178. action = "cusreceive",
  179. message = msgcontent,
  180. state = 1
  181. };
  182. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(cusmsg));
  183. await AddMessage(cussendsession.id, channel, "", msgcontent, new List<string>(), cussendsession.step);
  184. }
  185. if (bl)
  186. {
  187. var stepcount = await _chatprocessRepository.Count(p => p.isdelete == 0);
  188. var stepresultcount = cussendsession.stepresult.Count();
  189. cussendsession.step = stepresultcount + 2;
  190. if (stepresultcount < stepcount)
  191. {
  192. cussendsession.stepresult.Add(value);
  193. if (stepresultcount + 1 < stepcount)
  194. {
  195. iscomplete = false;
  196. await SystemReply(cussendsession);
  197. }
  198. }
  199. await _chatsessionRepository.UpdateOne(cussendsession);
  200. }
  201. }
  202. if(iscomplete)
  203. {
  204. var cusmsg = new
  205. {
  206. action = "cusreceive",
  207. message = "你的诉求已经记录,请等待处理结果!",
  208. state = 1
  209. };
  210. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(cusmsg));
  211. }
  212. #endregion
  213. }
  214. if (cussendsession.sertype == 2)//人工客服
  215. {
  216. #region 人工客服
  217. var connseruser = sessionusers.Where(p => p.type == 2).FirstOrDefault();
  218. if (connseruser.isonline == 0)//客服不在线
  219. {
  220. msg["state"] = 0;
  221. msg["message"] = "客服忙,请稍后!";
  222. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  223. }
  224. else//客服在线
  225. {
  226. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  227. var serntcmsg = new
  228. {
  229. action = "serreceive",
  230. message = msg["message"].ToString(),
  231. sessionid = cussendsession.id,
  232. conncususer.usercode,
  233. conncususer.name,
  234. conncususer.headimgurl,
  235. state = 1
  236. };
  237. await SendMsgToRemotePoint(connseruser.connectionid, JsonConvert.SerializeObject(serntcmsg));
  238. }
  239. #endregion
  240. }
  241. #endregion
  242. break;
  243. case "custurn":
  244. #region 客户转人工或转系统
  245. var turnsessionid = msg["sessionid"].ToString();
  246. var turnsendsession = _chatsessionRepository.GetSingle(turnsessionid).Result;
  247. var turnsessionusers = turnsendsession.chatusers;
  248. var connturnuser = turnsessionusers.Where(p => p.connectionid == Context.ConnectionId).FirstOrDefault();
  249. string turnmessage = string.Empty;
  250. if (turnsendsession.sertype == 1)//系统客服
  251. {
  252. #region 转人工回复
  253. msg["state"] = 0;
  254. if (await SplitCustomer(turnsendsession))
  255. {
  256. msg["message"] = "转人工回复!";
  257. turnmessage = "转人工回复成功";
  258. }
  259. else
  260. {
  261. msg["message"] = "客服忙,请稍后!";
  262. turnmessage = "转人工回复失败";
  263. }
  264. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  265. await AddMessage(turnsendsession.id, channel, connturnuser.usercode, turnmessage, new List<string>(), turnsendsession.step);
  266. #endregion
  267. }
  268. else if (turnsendsession.sertype == 2)//人工客服
  269. {
  270. #region 转机器回复
  271. await AddMessage(turnsendsession.id, channel, connturnuser.usercode, "转机器回复成功", new List<string>(), turnsendsession.step);
  272. var stepcount = await _chatprocessRepository.Count(p => p.isdelete == 0);
  273. if (turnsendsession.step > stepcount)
  274. {
  275. msg["state"] = 0;
  276. msg["message"] = "转机器回复!";
  277. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  278. await SystemReply(turnsendsession);
  279. }
  280. else
  281. {
  282. msg["state"] = 1;
  283. msg["message"] = "你的诉求已经记录,请等待处理结果!";
  284. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  285. }
  286. #endregion
  287. }
  288. #endregion
  289. break;
  290. case "serconn":
  291. #region 客服连接
  292. Chat_InOut sercio = new Chat_InOut();
  293. sercio.channel = msg["channel"] != null ? Int32.Parse(msg["channel"].ToString()) : 0;
  294. sercio.intime = DateTime.Now;
  295. sercio.ip = ip;
  296. sercio.connectionid = Context.ConnectionId;
  297. sercio.type = 2;
  298. sercio.isseat = 1;
  299. sercio.usercode = msg["usercode"]?.ToString() ?? "";
  300. sercio.name = msg["name"]?.ToString() ?? "";
  301. sercio.headimgurl = msg["headimgurl"]?.ToString() ?? "";
  302. sercio.isdelete = 0;
  303. sercio.createtime = DateTime.Now;
  304. sercio.createuser = msg["usercode"]?.ToString() ?? "";
  305. await _chatinoutRepository.Add(sercio);
  306. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  307. Servicers.Remove(Servicers.Where(p => p.UserCode == sercio.usercode).FirstOrDefault());
  308. Servicers.Remove(Servicers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault());
  309. ChatClass.Servicer servicer = new ChatClass.Servicer();
  310. servicer.ConnectionId = Context.ConnectionId;
  311. servicer.UserCode = sercio.usercode;
  312. Servicers.Add(servicer);
  313. #endregion
  314. break;
  315. case "sersession":
  316. #region 客服会话
  317. var usercode = msg["usercode"].ToString();
  318. var connusercode = msg["connusercode"].ToString();
  319. var inout = _chatinoutRepository.Get(p => p.usercode == usercode && p.outtime == null).Result.OrderByDescending(p=>p.intime).FirstOrDefault();
  320. var conninout = _chatinoutRepository.Get(p => p.usercode == connusercode && p.outtime == null).Result.OrderByDescending(p => p.intime).FirstOrDefault();
  321. var sersess = _chatsessionRepository.Get(p => p.type == 2).Result.ToList();
  322. var serses = sersess.Where(p => p.chatusers.Select(q => q.usercode).Contains(usercode)
  323. && p.chatusers.Select(q => q.usercode).Contains(connusercode)).ToList().FirstOrDefault();
  324. if (serses == null)
  325. {
  326. serses = new Chat_Session();
  327. chatuser fuser = new chatuser();
  328. fuser.connectionid = Context.ConnectionId;
  329. fuser.usercode = usercode;
  330. fuser.name = inout.name;
  331. fuser.headimgurl = inout.headimgurl;
  332. fuser.ip = ip;
  333. fuser.isonline = 1;
  334. serses.chatusers.Add(fuser);
  335. chatuser tuser = new chatuser();
  336. tuser.usercode = connusercode;
  337. if (conninout != null)
  338. {
  339. tuser.connectionid = conninout.connectionid;
  340. tuser.name = conninout.name;
  341. tuser.headimgurl = conninout.headimgurl;
  342. tuser.ip = conninout.ip;
  343. tuser.isonline = 1;
  344. }
  345. else
  346. {
  347. tuser.isonline = 0;
  348. }
  349. serses.chatusers.Add(tuser);
  350. serses.state = 1;
  351. serses.isdelete = 0;
  352. serses.createtime = DateTime.Now;
  353. serses.type = 2;
  354. serses.sertype = 1;
  355. serses.step = 1;
  356. serses.stepresult = new List<string>();
  357. serses.id = await _chatsessionRepository.AddRetID(serses);
  358. }
  359. else
  360. {
  361. serses.chatusers = new List<chatuser>();
  362. chatuser fuser = new chatuser();
  363. fuser.connectionid = Context.ConnectionId;
  364. fuser.usercode = usercode;
  365. fuser.name = inout.name;
  366. fuser.headimgurl = inout.headimgurl;
  367. fuser.ip = ip;
  368. fuser.isonline = 1;
  369. serses.chatusers.Add(fuser);
  370. chatuser tuser = new chatuser();
  371. tuser.usercode = connusercode;
  372. if (conninout != null)
  373. {
  374. tuser.connectionid = conninout.connectionid;
  375. tuser.name = conninout.name;
  376. tuser.headimgurl = conninout.headimgurl;
  377. tuser.ip = conninout.ip;
  378. tuser.isonline = 1;
  379. }
  380. else
  381. {
  382. tuser.isonline = 0;
  383. }
  384. serses.chatusers.Add(tuser);
  385. await _chatsessionRepository.UpdateOne(serses);
  386. }
  387. msg["sessionid"] = serses.id;
  388. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  389. #endregion
  390. break;
  391. case "sersend":
  392. #region 客服发送消息
  393. var sersessionid = msg["sessionid"].ToString();
  394. var sersendsession = _chatsessionRepository.GetSingle(sersessionid).Result;
  395. var sersessionusers = sersendsession.chatusers;
  396. var connsersenduser = sersessionusers.Where(p => p.connectionid == Context.ConnectionId).FirstOrDefault();
  397. await AddMessage(sersendsession.id, channel, connsersenduser.usercode, msg["message"].ToString(), new List<string>(), sersendsession.step);
  398. if (sersendsession.type == 1)
  399. {
  400. var conncussenduser = sersessionusers.Where(p => p.type == 1).FirstOrDefault();
  401. //if (conncussenduser.isonline == 0)
  402. if (Customers.Where(p => p.ConnectionId == conncussenduser.connectionid).FirstOrDefault() == null)
  403. {
  404. msg["state"] = 0;
  405. msg["message"] = "客户已下线";
  406. }
  407. else
  408. {
  409. var serntcmsg = new
  410. {
  411. action = "cusreceive",
  412. message = msg["message"].ToString(),
  413. state = 1
  414. };
  415. await SendMsgToRemotePoint(conncussenduser.connectionid, JsonConvert.SerializeObject(serntcmsg));
  416. }
  417. }
  418. else
  419. {
  420. var conncussenduser = sersessionusers.Where(p => p.connectionid != Context.ConnectionId).FirstOrDefault();
  421. //if(conncussenduser.isonline == 0)
  422. if (Servicers.Where(p => p.ConnectionId == conncussenduser.connectionid).FirstOrDefault() == null)
  423. {
  424. msg["state"] = 0;
  425. msg["message"] = conncussenduser.name + "已下线";
  426. }
  427. else
  428. {
  429. var serntcmsg = new
  430. {
  431. action = "serreceive",
  432. message = msg["message"].ToString(),
  433. sessionid = sersessionid,
  434. conncussenduser.usercode,
  435. conncussenduser.name,
  436. conncussenduser.headimgurl,
  437. state = 1
  438. };
  439. await SendMsgToRemotePoint(conncussenduser.connectionid, JsonConvert.SerializeObject(serntcmsg));
  440. }
  441. }
  442. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  443. #endregion
  444. break;
  445. default: await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));break;
  446. }
  447. }
  448. catch(Exception ex)
  449. {
  450. _logger.LogError(ex.Message.ToString());
  451. try
  452. {
  453. JObject msg = JsonConvert.DeserializeObject<JObject>(message);
  454. msg["state"] = 0;
  455. msg["message"] = "操作失败";
  456. await Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg));
  457. }
  458. catch
  459. {
  460. await Clients.Caller.SendAsync("ReceiveMessage", message);
  461. }
  462. }
  463. }
  464. /// <summary>
  465. /// 加入组
  466. /// </summary>
  467. /// <param name="groupName"></param>
  468. /// <returns></returns>
  469. public async Task JoinGroup(string groupName)
  470. {
  471. await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
  472. }
  473. /// <summary>
  474. /// 离开组
  475. /// </summary>
  476. /// <param name="groupName"></param>
  477. /// <returns></returns>
  478. public async Task LeaveGroup(string groupName)
  479. {
  480. await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
  481. }
  482. /// <summary>
  483. /// 连接事件
  484. /// </summary>
  485. /// <returns></returns>
  486. public override async Task OnConnectedAsync()
  487. {
  488. lock (lockobj)
  489. {
  490. ConnectionIds.Add(Context.ConnectionId);
  491. var msg = new
  492. {
  493. action = "conn",
  494. state = 1
  495. };
  496. Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg)).Wait();
  497. }
  498. await base.OnConnectedAsync();
  499. }
  500. /// <summary>
  501. /// 断开连接事件
  502. /// </summary>
  503. /// <param name="exception"></param>
  504. /// <returns></returns>
  505. public override async Task OnDisconnectedAsync(Exception exception)
  506. {
  507. await base.OnDisconnectedAsync(exception);
  508. lock (lockobj)
  509. {
  510. ConnectionIds.Remove(Context.ConnectionId);
  511. var cus = Customers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault();
  512. if (cus != null)//客户断线
  513. {
  514. var session = _chatsessionRepository.GetSingle(cus.SessionID).Result;
  515. session.state = 0;
  516. _chatsessionRepository.UpdateOne(session).Wait();
  517. if (!string.IsNullOrEmpty(cus.ServicerConnectionId))
  518. {
  519. var ser = Servicers.Where(p => p.ConnectionId == cus.ServicerConnectionId).FirstOrDefault();
  520. if (ser != null)
  521. {
  522. var serntcmsg = new
  523. {
  524. action = "serreceive",
  525. message = "客户下线",
  526. sessionid = cus.SessionID,
  527. state = 0
  528. };
  529. SendMsgToRemotePoint(cus.ServicerConnectionId, JsonConvert.SerializeObject(serntcmsg)).Wait();
  530. ser.Count = ser.Count - 1;
  531. }
  532. }
  533. Customers.Remove(cus);
  534. }
  535. else
  536. {
  537. var ser = Servicers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault();
  538. if (ser != null)//客服断线
  539. {
  540. Servicers.Remove(ser);
  541. var cuss = Customers.Where(p => p.ServicerConnectionId == Context.ConnectionId);
  542. foreach (var cusa in cuss)
  543. {
  544. var session = _chatsessionRepository.GetSingle(cusa.SessionID).Result;
  545. if (Servicers.Count == 0)
  546. {
  547. cusa.ServicerConnectionId = "";
  548. var cusntcmsg = new
  549. {
  550. action = "cusreceive",
  551. message = "客服忙,已经转为机器回复!",
  552. sessionid = cusa.SessionID,
  553. state = 0
  554. };
  555. SendMsgToRemotePoint(cusa.ConnectionId, JsonConvert.SerializeObject(cusntcmsg)).Wait();
  556. SystemReply(session).Wait();
  557. }
  558. else
  559. {
  560. SplitCustomer(session).Wait();
  561. }
  562. }
  563. }
  564. }
  565. var inout = _chatinoutRepository.Get(p => p.connectionid == Context.ConnectionId).Result.FirstOrDefault();
  566. if (inout != null)
  567. {
  568. inout.outtime = DateTime.Now;
  569. _chatinoutRepository.UpdateOne(inout).Wait();
  570. }
  571. var msg = new
  572. {
  573. action = "disconn",
  574. state = 1
  575. };
  576. Clients.Caller.SendAsync("ReceiveMessage", JsonConvert.SerializeObject(msg)).Wait();
  577. }
  578. }
  579. /// <summary>
  580. /// 获取ip
  581. /// </summary>
  582. /// <returns></returns>
  583. public string getipaddress()
  584. {
  585. var context = Context.GetHttpContext();
  586. var ip = context.Request.Headers["X-Forwarded-For"];
  587. if (string.IsNullOrEmpty(ip))
  588. {
  589. ip = context.Connection.RemoteIpAddress.ToString();
  590. }
  591. return ip;
  592. }
  593. /// <summary>
  594. /// 发送消息到
  595. /// </summary>
  596. /// <param name="ConnectionId"></param>
  597. /// <param name="msg"></param>
  598. private async Task<bool> SendMsgToRemotePoint(string ConnectionId, string msg)
  599. {
  600. try
  601. {
  602. await Clients.Client(ConnectionId).SendAsync("ReceiveMessage", msg);
  603. return true;
  604. }
  605. catch
  606. {
  607. return false;
  608. }
  609. }
  610. /// <summary>
  611. /// 系统流程回复
  612. /// </summary>
  613. /// <param name="session"></param>
  614. /// <returns></returns>
  615. private async Task<bool> SystemReply(Chat_Session session)
  616. {
  617. //系统流程回复
  618. var tuser = session.chatusers.Where(p => p.type == 1).FirstOrDefault();
  619. if (session.sertype == 2)
  620. {
  621. session.sertype = 1;
  622. session.chatusers = new List<chatuser> { tuser };
  623. await _chatsessionRepository.UpdateOne(session);
  624. }
  625. var step = _chatprocessRepository.Get(p => p.isdelete == 0 && p.step == session.step).Result.FirstOrDefault();
  626. if (step != null)
  627. {
  628. var options = new List<string>();
  629. if (step.optiontype == 1)
  630. {
  631. var optionlist = await _sys_dictionaryValuerepository.Get(p => p.dictionarycode == step.dictionarycode && p.statetype == true);
  632. options = optionlist.Select(p => p.name).ToList();
  633. }
  634. if (step.optiontype == 2)
  635. {
  636. options = step.options;
  637. }
  638. var cusmsg = new
  639. {
  640. action = "cusreceive",
  641. message = step.content,
  642. options,
  643. state = 1
  644. };
  645. await SendMsgToRemotePoint(tuser.connectionid, JsonConvert.SerializeObject(cusmsg));
  646. await AddMessage(session.id, 0, "", step.content, options, step.step);
  647. return true;
  648. }
  649. else
  650. {
  651. return false;
  652. }
  653. }
  654. /// <summary>
  655. /// 分配客服
  656. /// </summary>
  657. /// <param name="ConnectionId"></param>
  658. /// <param name="msg"></param>
  659. /// <returns></returns>
  660. private async Task<bool> SplitCustomer(Chat_Session session)
  661. {
  662. var fuser = session.chatusers.Where(p => p.type == 1).FirstOrDefault();
  663. //var serusers = await _chatinoutRepository.Get(p => p.type == 2 && p.isseat == 1 && p.outtime == null);
  664. var serusers = Servicers;
  665. if (serusers.Count() > 0)
  666. {
  667. //var cus = _chatsessionRepository.Get(q => q.state == 1 && q.type == 1).Result.ToList();
  668. //var sercuscount = serusers.ToList().Select(p => new
  669. //{
  670. // p.connectionid,
  671. // p.headimgurl,
  672. // p.intime,
  673. // p.name,
  674. // p.usercode,
  675. // cuscount = cus.Count(q => q.chatusers.Where(x => x.type == 2).Select(x => x.connectionid).Contains(p.connectionid))
  676. //});
  677. //var seruser = sercuscount.OrderBy(p => p.cuscount).ThenBy(p => p.intime).FirstOrDefault();
  678. var selseruser = serusers.OrderBy(p => p.Count).FirstOrDefault();
  679. var seruser = _chatinoutRepository.Get(p => p.connectionid == selseruser.ConnectionId).Result.FirstOrDefault();
  680. var tuser = session.chatusers.Where(p => p.type == 2).FirstOrDefault();
  681. if (tuser != null)
  682. {
  683. tuser.connectionid = seruser.connectionid;
  684. tuser.usercode = seruser.usercode;
  685. tuser.name = seruser.name;
  686. tuser.headimgurl = seruser.headimgurl;
  687. tuser.isonline = 1;
  688. tuser.type = 2;
  689. }
  690. else
  691. {
  692. tuser = new chatuser();
  693. tuser.connectionid = seruser.connectionid;
  694. tuser.usercode = seruser.usercode;
  695. tuser.name = seruser.name;
  696. tuser.headimgurl = seruser.headimgurl;
  697. tuser.isonline = 1;
  698. tuser.type = 2;
  699. session.chatusers.Add(tuser);
  700. }
  701. session.sertype = 2;
  702. var msg = new
  703. {
  704. action = "serreceive",
  705. message = "客户上线",
  706. sessionid = session.id,
  707. fuser.usercode,
  708. fuser.name,
  709. fuser.headimgurl,
  710. state = 0
  711. };
  712. await SendMsgToRemotePoint(tuser.connectionid, JsonConvert.SerializeObject(msg));
  713. await _chatsessionRepository.UpdateOne(session);
  714. var cususer = Customers.Where(p => p.ConnectionId == fuser.connectionid).FirstOrDefault();
  715. cususer.ServicerConnectionId = seruser.connectionid;
  716. selseruser.Count = selseruser.Count + 1;
  717. return true;
  718. }
  719. else
  720. {
  721. return false;
  722. }
  723. }
  724. /// <summary>
  725. /// 新增聊天记录
  726. /// </summary>
  727. /// <param name="session"></param>
  728. /// <returns></returns>
  729. private async Task AddMessage(string sessionid,int channel,string senduser, string content, List<string> options,int step)
  730. {
  731. Chat_Message chatmsg = new Chat_Message();
  732. chatmsg.sessionid = sessionid;
  733. chatmsg.channel = channel;
  734. chatmsg.senduser = senduser;
  735. chatmsg.content = content;
  736. chatmsg.options = options;
  737. chatmsg.step = step;
  738. chatmsg.state = 1;
  739. chatmsg.type = 1;
  740. chatmsg.channel = 0;
  741. chatmsg.isdelete = 0;
  742. chatmsg.createtime = DateTime.Now;
  743. await _chatmessageRepository.Add(chatmsg);
  744. }
  745. }
  746. }