PbxController.cs 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  1. using Hotline.Application.FlowEngine;
  2. using Hotline.Caching.Interfaces;
  3. using Hotline.CallCenter.Calls;
  4. using Hotline.CallCenter.Configs;
  5. using Hotline.CallCenter.Devices;
  6. using Hotline.CallCenter.Ivrs;
  7. using Hotline.CallCenter.Tels;
  8. using Hotline.Configurations;
  9. using Hotline.FlowEngine.WorkflowModules;
  10. using Hotline.FlowEngine.Workflows;
  11. using Hotline.Settings;
  12. using Hotline.Share.Dtos;
  13. using Hotline.Share.Dtos.CallCenter;
  14. using Hotline.Share.Dtos.FlowEngine;
  15. using Hotline.Share.Dtos.FlowEngine.Workflow;
  16. using Hotline.Share.Dtos.Trunk;
  17. using Hotline.Share.Enums.CallCenter;
  18. using Hotline.Share.Requests;
  19. using Hotline.Users;
  20. using MapsterMapper;
  21. using Microsoft.AspNetCore.Mvc;
  22. using Microsoft.Extensions.Options;
  23. using SqlSugar;
  24. using Wex.Sdk;
  25. using Wex.Sdk.Tel;
  26. using XF.Domain.Authentications;
  27. using XF.Domain.Cache;
  28. using XF.Domain.Exceptions;
  29. using XF.Domain.Repository;
  30. using XF.Utility.EnumExtensions;
  31. namespace Hotline.Api.Controllers
  32. {
  33. /// <summary>
  34. /// 话机设备管理
  35. /// </summary>
  36. public class PbxController : BaseController
  37. {
  38. private readonly ITelRepository _telRepository;
  39. private readonly ITelRestRepository _telRestRepository;
  40. private readonly ITelDomainService _telDomainService;
  41. private readonly ITypedCache<Tel> _cacheTel;
  42. private readonly ITypedCache<TelGroup> _cacheTelGroup;
  43. private readonly ITelGroupRepository _telGroupRepository;
  44. private readonly IMapper _mapper;
  45. private readonly IWorkRepository _workRepository;
  46. private readonly INewRockDeviceManager _newRockDeviceManager;
  47. private readonly IUserCacheManager _userCacheManager;
  48. private readonly ISessionContext _sessionContext;
  49. private readonly ICallRepository _callRepository;
  50. private readonly IRepository<TrunkIvrManager> _trunkIvrManagerRepository;
  51. private readonly IIvrCategoryRepository _ivrCategoryRepository;
  52. private readonly IWorkflowApplication _workflowApplication;
  53. private readonly IWorkflowDomainService _workflowDomainService;
  54. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  55. private readonly IIvrDomainService _ivrDomainService;
  56. private readonly IIvrCacheManager _ivrCacheManager;
  57. private readonly ILogger<TelController> _logger;
  58. private readonly ICallDetailRepository _callDetailRepository;
  59. private readonly IRepository<User> _userRepository;
  60. private readonly IWexClient _wexClient;
  61. private readonly IWexTelGroupRepository _wexTelGroupRepository;
  62. private readonly IOptionsSnapshot<CallCenterConfiguration> _options;
  63. public PbxController(
  64. IServiceProvider serviceProvider,
  65. ITelRepository telRepository,
  66. ITelRestRepository telRestRepository,
  67. ITelDomainService telDomainService,
  68. ITypedCache<Tel> cacheTel,
  69. ITypedCache<TelGroup> cacheTelGroup,
  70. ITelGroupRepository telGroupRepository,
  71. IMapper mapper,
  72. IWorkRepository workRepository,
  73. IUserCacheManager userCacheManager,
  74. ISessionContext sessionContext,
  75. ICallRepository callRepository,
  76. IRepository<TrunkIvrManager> trunkIvrManagerRepository,
  77. IIvrCategoryRepository ivrCategoryRepository,
  78. IWorkflowApplication workflowApplication,
  79. IWorkflowDomainService workflowDomainService,
  80. ISystemSettingCacheManager systemSettingCacheManager,
  81. IIvrDomainService ivrDomainService,
  82. IIvrCacheManager ivrCacheManager,
  83. ILogger<TelController> logger,
  84. ICallDetailRepository callDetailRepository,
  85. IRepository<User> userRepository,
  86. IWexClient wexClient,
  87. IWexTelGroupRepository wexTelGroupRepository,
  88. IOptionsSnapshot<AppConfiguration> appOptions,
  89. IOptionsSnapshot<CallCenterConfiguration> options)
  90. {
  91. _telRepository = telRepository;
  92. _telRestRepository = telRestRepository;
  93. _telDomainService = telDomainService;
  94. _cacheTel = cacheTel;
  95. _cacheTelGroup = cacheTelGroup;
  96. _telGroupRepository = telGroupRepository;
  97. _mapper = mapper;
  98. _workRepository = workRepository;
  99. _userCacheManager = userCacheManager;
  100. _sessionContext = sessionContext;
  101. _callRepository = callRepository;
  102. _trunkIvrManagerRepository = trunkIvrManagerRepository;
  103. _ivrCategoryRepository = ivrCategoryRepository;
  104. _workflowApplication = workflowApplication;
  105. _workflowDomainService = workflowDomainService;
  106. _systemSettingCacheManager = systemSettingCacheManager;
  107. _ivrDomainService = ivrDomainService;
  108. _ivrCacheManager = ivrCacheManager;
  109. _logger = logger;
  110. _callDetailRepository = callDetailRepository;
  111. _userRepository = userRepository;
  112. _wexClient = wexClient;
  113. _wexTelGroupRepository = wexTelGroupRepository;
  114. _options = options;
  115. if (appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XunShi)
  116. {
  117. _newRockDeviceManager = serviceProvider.GetRequiredService<INewRockDeviceManager>();
  118. }
  119. }
  120. #region 话机
  121. /// <summary>
  122. /// 根据设备自动同步分机数据到数据库
  123. /// </summary>
  124. /// <returns></returns>
  125. [HttpPut("sync-tels")]
  126. public async Task SyncTelsAsync()
  127. {
  128. var dbTels = await _telRepository.QueryAsync();
  129. foreach (var dbTel in dbTels)
  130. {
  131. _cacheTel.Remove(dbTel.No);
  132. }
  133. //await _telRepository.RemoveRangeAsync(dbTels);
  134. var tels = await _telDomainService.QueryTelsAsync(HttpContext.RequestAborted);
  135. var list = tels.ExceptBy(dbTels.Select(e => e.No), x => x.No).ToList();
  136. var delList = dbTels.ExceptBy(tels.Select(e => e.No), x => x.No).ToList();
  137. for (int i = 0; i < delList.Count; i++)
  138. {
  139. delList[i].SoftDelete();
  140. }
  141. await _telRepository.UpdateRangeAsync(delList);
  142. await _telRepository.AddRangeAsync(list);
  143. }
  144. /// <summary>
  145. /// 查询所有分机
  146. /// </summary>
  147. /// <returns></returns>
  148. [HttpGet("query-tels")]
  149. public async Task<IReadOnlyList<TelDto>> QueryTels()
  150. {
  151. var tels = await _telRepository.QueryExtAsync(d => true, d => d.Includes(x => x.Groups));
  152. return _mapper.Map<IReadOnlyList<TelDto>>(tels);
  153. }
  154. #endregion
  155. #region 分机组
  156. /// <summary>
  157. /// 页面基础信息
  158. /// </summary>
  159. /// <returns></returns>
  160. [HttpGet("base-info-group")]
  161. public async Task<dynamic> GetBaseInfoGroup()
  162. {
  163. return new
  164. {
  165. Distributions = EnumExts.GetDescriptions<EDistribution>()
  166. };
  167. }
  168. /// <summary>
  169. /// 查询所有分机组
  170. /// </summary>
  171. /// <returns></returns>
  172. [HttpGet("query-telgroups")]
  173. public async Task<IReadOnlyList<TelGroupDto>> QueryTelGroups()
  174. {
  175. var groups = await _telGroupRepository.QueryExtAsync(d => true, d => d.Includes(x => x.Tels));
  176. return _mapper.Map<IReadOnlyList<TelGroupDto>>(groups);
  177. }
  178. /// <summary>
  179. /// 新增分机组
  180. /// </summary>
  181. /// <param name="dto"></param>
  182. /// <returns></returns>
  183. [HttpPost("add-telgroup")]
  184. public async Task AddTelGroup([FromBody] AddTelGroupDto dto)
  185. {
  186. var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
  187. await _newRockDeviceManager.AssginConfigGroupAsync(
  188. _options.Value.NewRock, dto.No,
  189. dto.Distribution,
  190. ext: works.Select(d => d.TelNo).ToList(),
  191. voiceFile: dto.Voice ?? null,
  192. cancellationToken: HttpContext.RequestAborted);
  193. var group = _mapper.Map<TelGroup>(dto);
  194. var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
  195. group.Tels = tels;
  196. await _telGroupRepository.AddNavTelsAsync(group, HttpContext.RequestAborted);
  197. _cacheTelGroup.Remove(dto.No);
  198. }
  199. /// <summary>
  200. /// 更新分机组
  201. /// </summary>
  202. /// <param name="dto"></param>
  203. /// <returns></returns>
  204. [HttpPut("update-telgroup")]
  205. public async Task UpdateTelGroup([FromBody] UpdateTelGroupDto dto)
  206. {
  207. var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
  208. await _newRockDeviceManager.AssginConfigGroupAsync(
  209. _options.Value.NewRock, dto.No,
  210. dto.Distribution,
  211. ext: works.Select(d => d.TelNo).ToList(),
  212. voiceFile: dto.Voice ?? null,
  213. cancellationToken: HttpContext.RequestAborted);
  214. var group = _mapper.Map<TelGroup>(dto);
  215. var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
  216. group.Tels = tels;
  217. await _telGroupRepository.UpdateNavTelsAsync(group, HttpContext.RequestAborted);
  218. _cacheTelGroup.Remove(dto.No);
  219. }
  220. #endregion
  221. #region 话机设备操作
  222. /// <summary>
  223. /// 查询小休流程开启参数
  224. /// </summary>
  225. /// <returns></returns>
  226. [HttpGet("flow-start")]
  227. public async Task<NextStepsDto> GetFlowStartOptionsAsync()
  228. {
  229. //return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.TelRestApply,
  230. // HttpContext.RequestAborted);
  231. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.TelRestApply,
  232. HttpContext.RequestAborted);
  233. }
  234. /// <summary>
  235. /// 分机休息
  236. /// </summary>
  237. /// <returns></returns>
  238. [HttpPost("rest")]
  239. public async Task Rest([FromBody] StartRestDto dto)
  240. {
  241. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  242. if (work is null)
  243. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  244. bool isCanApply = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsRestApproval).SettingValue[0]);
  245. if (isCanApply)
  246. {
  247. var isApply = await _telRestRepository.IsApplyingAsync(work.TelNo, HttpContext.RequestAborted);
  248. if (isApply)
  249. throw new UserFriendlyException("分机休息申请正在审核阶段");
  250. }
  251. var isResting = await _telRestRepository.IsRestingAsync(work.TelNo, HttpContext.RequestAborted);
  252. if (isResting)
  253. throw new UserFriendlyException("当前坐席正在休息");
  254. var user = _userRepository.Get(work.UserId);
  255. var telRest = new TelRest(work.TelId, work.TelNo, work.UserId, work.UserName, dto.Reason, isCanApply, user.StaffNo);
  256. await _telRestRepository.AddAsync(telRest, HttpContext.RequestAborted);
  257. if (!isCanApply)
  258. {
  259. await _telDomainService.TelRestApplyPassAsync(telRest.Id, HttpContext.RequestAborted);
  260. }
  261. else
  262. {
  263. var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
  264. startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
  265. startWorkflowDto.Opinion = dto.Reason;
  266. startWorkflowDto.Title = "分机休息申请流程";
  267. // await _workflowApplication.StartWorkflowAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  268. //await _workflowDomainService.StartAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  269. await _workflowDomainService.StartToFirstStepAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  270. }
  271. }
  272. #region 威尔信小休
  273. /// <summary>
  274. /// 分机休息流程开始
  275. /// </summary>
  276. /// <param name="dto"></param>
  277. /// <returns></returns>
  278. [HttpPost("rest-flow")]
  279. public async Task RestFlow([FromBody] StartRestDto dto)
  280. {
  281. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  282. if (tel.Data == null || tel.Data.Count == 0)
  283. throw UserFriendlyException.SameMessage("未找到分机信息");
  284. if (tel.Data[0].Sigin == 0)
  285. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  286. var isApply = await _telRestRepository.IsApplyingAsync(tel.Data[0].TelNo, HttpContext.RequestAborted);
  287. if (isApply)
  288. throw UserFriendlyException.SameMessage("分机休息申请正在审核阶段");
  289. var isResting = await _telRestRepository.IsRestingAsync(tel.Data[0].TelNo, HttpContext.RequestAborted);
  290. if (isResting)
  291. throw new UserFriendlyException("当前坐席正在休息");
  292. var telRest = new TelRest(tel.Data[0].TelNo, tel.Data[0].TelNo, _sessionContext.RequiredUserId, _sessionContext.UserName, dto.Reason, true, _sessionContext.StaffNo);
  293. await _telRestRepository.AddAsync(telRest, HttpContext.RequestAborted);
  294. var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
  295. startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
  296. startWorkflowDto.Opinion = dto.Reason;
  297. startWorkflowDto.Title = "分机休息申请流程";
  298. // await _workflowApplication.StartWorkflowAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  299. //await _workflowDomainService.StartAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  300. await _workflowDomainService.StartToFirstStepAsync(startWorkflowDto, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  301. }
  302. /// <summary>
  303. /// 开始分机休息
  304. /// </summary>
  305. /// <returns></returns>
  306. [HttpGet("begin-rest")]
  307. public async Task BeginRest()
  308. {
  309. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  310. if (tel.Data == null || tel.Data.Count == 0)
  311. throw UserFriendlyException.SameMessage("未找到分机信息");
  312. if (tel.Data[0].Sigin == 0)
  313. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  314. var telRest = await _telRestRepository.GetAsync(x => !x.EndTime.HasValue && !x.StartTime.HasValue && x.TelNo == tel.Data[0].TelNo, HttpContext.RequestAborted);
  315. if (telRest == null)
  316. throw new UserFriendlyException($"错误");
  317. //if (string.IsNullOrEmpty(id))
  318. // throw UserFriendlyException.SameMessage("无效分机休息编号");
  319. //var telRest = await _telRestRepository.GetAsync(id, HttpContext.RequestAborted);
  320. //if (telRest == null)
  321. // throw new UserFriendlyException($"无效分机休息编号, telRestId: {id}", "无效分机休息编号");
  322. telRest.ApplyStatus = ETelRestApplyStatus.Resting;
  323. telRest.StartTime = DateTime.Now;
  324. await _telRestRepository.UpdateAsync(telRest, HttpContext.RequestAborted);
  325. }
  326. /// <summary>
  327. /// 分机休息
  328. /// </summary>
  329. /// <param name="dto"></param>
  330. /// <returns></returns>
  331. [HttpPost("rest-add")]
  332. public async Task Rest([FromBody] ResstDto dto)
  333. {
  334. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  335. if (tel.Data == null || tel.Data.Count == 0)
  336. throw UserFriendlyException.SameMessage("未找到分机信息");
  337. if (tel.Data[0].Sigin == 0)
  338. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  339. var telRest = new TelRest(tel.Data[0].TelNo, tel.Data[0].TelNo, _sessionContext.RequiredUserId, _sessionContext.UserName, dto.Reason, false, _sessionContext.StaffNo);
  340. await _telRestRepository.AddAsync(telRest, HttpContext.RequestAborted);
  341. }
  342. /// <summary>
  343. /// 删除分机休息
  344. /// </summary>
  345. /// <returns></returns>
  346. /// <exception cref="UserFriendlyException"></exception>
  347. [HttpGet("rest-del")]
  348. public async Task DelRest()
  349. {
  350. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  351. if (tel.Data == null || tel.Data.Count == 0)
  352. throw UserFriendlyException.SameMessage("未找到分机信息");
  353. if (tel.Data[0].Sigin == 0)
  354. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  355. var restingTel = await _telRestRepository.GetAsync(d => d.TelId == tel.Data[0].TelNo && !d.EndTime.HasValue, HttpContext.RequestAborted);
  356. if (restingTel is null)
  357. throw new UserFriendlyException("未查询到分机休息信息");
  358. await _telRestRepository.RemoveAsync(restingTel.Id, false, HttpContext.RequestAborted);
  359. }
  360. /// <summary>
  361. /// 分机结束休息(威尔信)
  362. /// </summary>
  363. /// <returns></returns>
  364. [HttpGet("un-rest-wex")]
  365. public async Task<TelRestDto> UnRestWEX()
  366. {
  367. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  368. if (tel.Data == null || tel.Data.Count == 0)
  369. throw UserFriendlyException.SameMessage("未找到分机信息");
  370. if (tel.Data[0].Sigin == 0)
  371. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  372. var telRest = await _telDomainService.UnRestWexAsync(tel.Data[0].TelNo, HttpContext.RequestAborted);
  373. return _mapper.Map<TelRestDto>(telRest);
  374. }
  375. #endregion
  376. /// <summary>
  377. /// 分机结束休息
  378. /// </summary>
  379. [HttpPut("un-rest")]
  380. public async Task<TelRestDto> UnRest()
  381. {
  382. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  383. if (work is null)
  384. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  385. var telRest = await _telDomainService.UnRestAsync(work.TelId, HttpContext.RequestAborted);
  386. return _mapper.Map<TelRestDto>(telRest);
  387. }
  388. /// <summary>
  389. /// 保持通话
  390. /// </summary>
  391. [HttpPut("hold")]
  392. public async Task Hold(string callId)
  393. {
  394. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  395. if (work is null)
  396. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  397. await _telDomainService.HoldAsync(work.TelId, _sessionContext.RequiredUserId, _sessionContext.UserName, callId, HttpContext.RequestAborted);
  398. }
  399. /// <summary>
  400. /// 恢复通话(解除hold状态)
  401. /// </summary>
  402. [HttpPut("un-hold")]
  403. public async Task UnHold(string callId)
  404. {
  405. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  406. if (work is null)
  407. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  408. await _telDomainService.UnHoldAsync(work.TelId, _sessionContext.RequiredUserId, callId, HttpContext.RequestAborted);
  409. }
  410. /// <summary>
  411. /// 分机呼分机
  412. /// </summary>
  413. /// <returns></returns>
  414. [HttpPost("tel-to-tel")]
  415. public async Task TelToTel([FromBody] TelToTelDto dto)
  416. {
  417. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  418. if (work is null)
  419. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  420. //获取对方是否在工作
  421. var toWork = _userCacheManager.GetWorkByTel(dto.TelNo);
  422. if (toWork is null)
  423. throw UserFriendlyException.SameMessage("转接分机未进行工作");
  424. //判断分机状态
  425. var telState = await _newRockDeviceManager.QueryTelState(_options.Value.NewRock, dto.TelNo, HttpContext.RequestAborted);
  426. if (telState != ETelStatus.Ready)
  427. throw UserFriendlyException.SameMessage("被叫分机不在线或正在通话中");
  428. bool isRest = await _telRestRepository.IsRestingAsync(dto.TelNo, HttpContext.RequestAborted);
  429. if (isRest)
  430. throw new UserFriendlyException("被叫分机正在休息不能转接");
  431. await _newRockDeviceManager.ExtToExtAsync(_options.Value.NewRock, work.TelNo, dto.TelNo, HttpContext.RequestAborted);
  432. }
  433. /// <summary>
  434. /// 分机拨打外部电话
  435. /// </summary>
  436. /// <param name="dto"></param>
  437. /// <returns></returns>
  438. [HttpPost("tel-to-outer")]
  439. public async Task TelToOuter([FromBody] TelToOuterDto dto)
  440. {
  441. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  442. if (work is null)
  443. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  444. await _newRockDeviceManager.ExtToOuterAsync(_options.Value.NewRock, work.TelNo, dto.OuterNo, HttpContext.RequestAborted);
  445. }
  446. /// <summary>
  447. /// 指定模拟外线外呼(分机拨打外部电话)
  448. /// OM设备多个外线时调用此接口
  449. /// </summary>
  450. /// <param name="dto"></param>
  451. /// <returns></returns>
  452. [HttpPost("tel-to-outer-line")]
  453. public async Task TelToOuterByLine([FromBody] TelToOuterByLineDto dto)
  454. {
  455. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  456. if (work is null)
  457. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  458. string newOuter = dto.LineId + "," + dto.OuterNo;
  459. await _newRockDeviceManager.ExtToOuterAsync(_options.Value.NewRock, work.TelNo, newOuter, HttpContext.RequestAborted);
  460. }
  461. /// <summary>
  462. /// 来电转分机
  463. /// </summary>
  464. /// <param name="dto"></param>
  465. /// <returns></returns>
  466. [HttpPost("visitor-to-tel")]
  467. public async Task VisitorToTel([FromBody] VisitorToTelDto dto)
  468. {
  469. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  470. if (work is null)
  471. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  472. var toWork = _userCacheManager.GetWorkByTel(dto.TelNo);
  473. if (toWork is null)
  474. throw UserFriendlyException.SameMessage("转接分机未进行工作");
  475. var totelState = await _newRockDeviceManager.QueryTelState(_options.Value.NewRock, dto.TelNo, HttpContext.RequestAborted);
  476. if (totelState != ETelStatus.Ready)
  477. throw UserFriendlyException.SameMessage("被叫分机不在线或正在通话中");
  478. bool isRest = await _telRestRepository.IsRestingAsync(dto.TelNo, HttpContext.RequestAborted);
  479. if (isRest)
  480. throw new UserFriendlyException("被叫分机正在休息不能转接");
  481. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  482. if (!string.IsNullOrEmpty(tel.ConversationId))
  483. await _newRockDeviceManager.VisitorToExtAsync(_options.Value.NewRock, tel.ConversationId, dto.TelNo, HttpContext.RequestAborted);
  484. else
  485. throw UserFriendlyException.SameMessage("当前分机没有通话");
  486. }
  487. /// <summary>
  488. /// 来电转外部电话
  489. /// </summary>
  490. /// <param name="dto"></param>
  491. /// <returns></returns>
  492. [HttpPost("visitor-to-outer")]
  493. public async Task VisitorToOuter([FromBody] VisitorToOuterDto dto)
  494. {
  495. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  496. if (work is null)
  497. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  498. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  499. if (!string.IsNullOrEmpty(tel.ConversationId))
  500. await _newRockDeviceManager.VisitorToOuterAsync(_options.Value.NewRock, tel.ConversationId, dto.OuterNo, HttpContext.RequestAborted);
  501. else
  502. throw UserFriendlyException.SameMessage("当前分机没有通话");
  503. }
  504. /// <summary>
  505. /// 来电转分机组队列
  506. /// </summary>
  507. /// <param name="dto"></param>
  508. /// <returns></returns>
  509. [HttpPost("visitor-to-group")]
  510. public async Task VisitorToGroup([FromBody] VisitorToGroupDto dto)
  511. {
  512. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  513. if (work is null)
  514. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  515. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  516. if (!string.IsNullOrEmpty(tel.ConversationId))
  517. await _newRockDeviceManager.VisitorToGroupAsync(_options.Value.NewRock, tel.ConversationId, dto.groupid, HttpContext.RequestAborted);
  518. else
  519. throw UserFriendlyException.SameMessage("当前分机没有通话");
  520. }
  521. /// <summary>
  522. /// 去电转外部电话
  523. /// </summary>
  524. /// <param name="dto"></param>
  525. /// <returns></returns>
  526. /// <exception cref="UserFriendlyException"></exception>
  527. [HttpPost("outer-to-outer")]
  528. public async Task OuterToOuter([FromBody] OuterToOuterDto dto)
  529. {
  530. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  531. if (work is null)
  532. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  533. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  534. if (!string.IsNullOrEmpty(tel.ConversationId))
  535. await _newRockDeviceManager.OuterToOuterAsync(_options.Value.NewRock, tel.ConversationId, dto.OuterNo, HttpContext.RequestAborted);
  536. else
  537. throw UserFriendlyException.SameMessage("当前分机没有通话");
  538. }
  539. /// <summary>
  540. /// 去电转分机
  541. /// </summary>
  542. /// <param name="dto"></param>
  543. /// <returns></returns>
  544. /// <exception cref="UserFriendlyException"></exception>
  545. [HttpPost("outer-to-tel")]
  546. public async Task OuterToTel([FromBody] OuterToTelDto dto)
  547. {
  548. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  549. if (work is null)
  550. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  551. var toWork = _userCacheManager.GetWorkByTel(dto.TelNo);
  552. if (toWork is null)
  553. throw UserFriendlyException.SameMessage("转接分机未进行工作");
  554. var totelState = await _newRockDeviceManager.QueryTelState(_options.Value.NewRock, dto.TelNo, HttpContext.RequestAborted);
  555. if (totelState != ETelStatus.Ready)
  556. throw UserFriendlyException.SameMessage("被叫分机不在线或正在通话中");
  557. bool isRest = await _telRestRepository.IsRestingAsync(dto.TelNo, HttpContext.RequestAborted);
  558. if (isRest)
  559. throw new UserFriendlyException("被叫分机正在休息不能转接");
  560. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  561. if (!string.IsNullOrEmpty(tel.ConversationId))
  562. await _newRockDeviceManager.OuterToExtAsync(_options.Value.NewRock, tel.ConversationId, dto.TelNo, HttpContext.RequestAborted);
  563. else
  564. throw UserFriendlyException.SameMessage("当前分机没有通话");
  565. }
  566. /// <summary>
  567. /// 三方会议
  568. /// 先建立两方通话,然后调用保持通话接口,拨通第三方分机,然后再调用三方会议接口
  569. /// 1. 分机 A 正在和 B 通话;
  570. /// 2. 分机 A 把原通话呼叫保持;
  571. /// 3. 分机 A 向 C 发起新的呼叫,并建立通话;
  572. /// 4. 此时,使用该 API 能够实现以分机 A 为主持方建立 A、B、C 的三方会议。
  573. /// </summary>
  574. /// <param name="dto">TelNo:会议发起方分机号</param>
  575. /// <returns></returns>
  576. /// <exception cref="UserFriendlyException"></exception>
  577. [HttpPost("meeting")]
  578. public async Task Conference([FromBody] ConferenceDto dto)
  579. {
  580. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  581. if (work is null)
  582. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  583. var tel = await _newRockDeviceManager.QueryTelAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  584. if (!string.IsNullOrEmpty(tel.ConversationId))
  585. await _newRockDeviceManager.ConferenceMeetingAsync(_options.Value.NewRock, dto.TelNo, HttpContext.RequestAborted);
  586. else
  587. throw UserFriendlyException.SameMessage("当前分机没有通话");
  588. }
  589. #region 监听和强插
  590. /// <summary>
  591. /// 监听分机
  592. /// </summary>
  593. /// <param name="request"></param>
  594. /// <returns></returns>
  595. [HttpPost("monitor-ext")]
  596. public async Task MonitorExt([FromBody] MonitorExtRequest request)
  597. {
  598. await _newRockDeviceManager.MonitorExtAsync(_options.Value.NewRock, request.firstTelNo, request.secondTelNo, HttpContext.RequestAborted);
  599. }
  600. /// <summary>
  601. /// 从监听到插播状态变换
  602. /// 1. 已知:分机 A 在监听分机 B 与其通话方的通话;
  603. /// 2. 执行分机 A 的从监听到插播状态变换的 API;
  604. /// 3. 执行成功时,分机 A 与分机 B 建立通话,分机 B 的原通话方听保持音。
  605. /// </summary>
  606. /// <param name="request"></param>
  607. /// <returns></returns>
  608. [HttpPost("monitor-ext-to-talk")]
  609. public async Task MonitorExtToTalk([FromBody] MonitorExtToTalkRequest request)
  610. {
  611. await _newRockDeviceManager.MonitorExtToTalkAsync(_options.Value.NewRock, request.telNo, HttpContext.RequestAborted);
  612. }
  613. /// <summary>
  614. /// 从插播到监听状态变换
  615. /// 1. 已知:分机 A 在插播分机 B 的通话;
  616. /// 2. 执行分机 A 的从插播到监听状态变换的 API;
  617. /// 3. 执行成功时,分机 A 监听分机 B 及其原通话方的通话。
  618. /// </summary>
  619. /// <param name="request"></param>
  620. /// <returns></returns>
  621. [HttpPost("monitor-ext-to-listen")]
  622. public async Task MonitorExtToListen([FromBody] MonitorExtToListenRequest request)
  623. {
  624. await _newRockDeviceManager.MonitorExtToListenAsync(_options.Value.NewRock, request.telNo, HttpContext.RequestAborted);
  625. }
  626. #endregion
  627. #region 强插
  628. /// <summary>
  629. /// 强插
  630. /// 1. 已知:分机 A 当前空闲,分机 B 正在通话中;
  631. /// 2. 执行分机 A 强插分机 B 的 API;
  632. /// 3. 执行成功时,分机 A 振铃,摘机后即可形成三方通话。
  633. /// </summary>
  634. /// <param name="request"></param>
  635. /// <returns></returns>
  636. [HttpPost("bargein-ext")]
  637. public async Task BargeinExt([FromBody] BargeinExtRequest request)
  638. {
  639. await _newRockDeviceManager.BargeinExtAsync(_options.Value.NewRock, request.firstTelNo, request.secondTelNo, HttpContext.RequestAborted);
  640. }
  641. #endregion
  642. #region 强拆
  643. /// <summary>
  644. /// 强拆分机
  645. /// </summary>
  646. /// <param name="request"></param>
  647. /// <returns></returns>
  648. [HttpPost("clear-ext")]
  649. public async Task ClearExt([FromBody] ClearExtRequest request)
  650. {
  651. //查询当前通话记录
  652. //var call = await _callRepository.GetAsync(request.CallId, HttpContext.RequestAborted);
  653. //if (call is null)
  654. // throw UserFriendlyException.SameMessage("无效通话,无法挂断");
  655. //if (call.CallStatus == ECallStatus.Bye)
  656. // throw UserFriendlyException.SameMessage("通话已结束");
  657. await _newRockDeviceManager.ClearExtAsync(_options.Value.NewRock, request.CallId, HttpContext.RequestAborted);
  658. }
  659. /// <summary>
  660. /// 强拆来电
  661. /// </summary>
  662. /// <param name="request"></param>
  663. /// <returns></returns>
  664. [HttpPost("clear-visitor")]
  665. public async Task ClearVisitor([FromBody] ClearVisitorRequest request)
  666. {
  667. //查询当前通话记录
  668. var call = await _callRepository.GetAsync(request.CallId, HttpContext.RequestAborted);
  669. if (call is null)
  670. throw UserFriendlyException.SameMessage("无效通话,无法挂断");
  671. if (call.CallStatus == ECallStatus.Bye)
  672. throw UserFriendlyException.SameMessage("通话已结束");
  673. await _newRockDeviceManager.ClearVisitorAsync(_options.Value.NewRock, call.ConversationId, HttpContext.RequestAborted);
  674. }
  675. /// <summary>
  676. /// 强拆去电
  677. /// </summary>
  678. /// <param name="request"></param>
  679. /// <returns></returns>
  680. [HttpPost("clear-outer")]
  681. public async Task ClearOuter([FromBody] ClearOuterRequest request)
  682. {
  683. //查询当前通话记录
  684. var call = await _callRepository.GetAsync(request.CallId, HttpContext.RequestAborted);
  685. if (call is null)
  686. throw UserFriendlyException.SameMessage("无效通话,无法挂断");
  687. if (call.CallStatus == ECallStatus.Bye)
  688. throw UserFriendlyException.SameMessage("通话已结束");
  689. await _newRockDeviceManager.ClearOuterAsync(_options.Value.NewRock, call.ConversationId, HttpContext.RequestAborted);
  690. }
  691. #endregion
  692. #region 静音和取消静音
  693. /// <summary>
  694. /// 静音
  695. /// </summary>
  696. /// <returns></returns>
  697. [HttpGet("mute")]
  698. public async Task Mute()
  699. {
  700. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  701. if (work is null)
  702. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  703. await _newRockDeviceManager.MuteAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  704. }
  705. /// <summary>
  706. /// 取消静音
  707. /// </summary>
  708. /// <returns></returns>
  709. [HttpGet("unmute")]
  710. public async Task UnMute()
  711. {
  712. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  713. if (work is null)
  714. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  715. await _newRockDeviceManager.UnMuteAsync(_options.Value.NewRock, work.TelNo, HttpContext.RequestAborted);
  716. }
  717. #endregion
  718. #endregion
  719. #region 线路管理
  720. /// <summary>
  721. /// 获取线路列表
  722. /// </summary>
  723. /// <returns></returns>
  724. [HttpGet("trunk-list")]
  725. public async Task<IReadOnlyList<TrunkIvrManager>> GetTrunkList()
  726. {
  727. return await _trunkIvrManagerRepository.Queryable()
  728. .Includes(d => d.WorkCategoryModel)
  729. .Includes(d => d.RestCategoryModel)
  730. .Includes(d => d.WorkToGroupModel.MappingField(z => z.No, () => d.WorkToGroup))
  731. .Includes(d => d.RestToGroupModel.MappingField(z => z.No, () => d.RestToGroup))
  732. .ToListAsync();
  733. }
  734. /// <summary>
  735. /// 获取线路对象
  736. /// </summary>
  737. /// <param name="id"></param>
  738. /// <returns></returns>
  739. [HttpGet("trunk/{id}")]
  740. public async Task<TrunkIvrManager> GetTrunk(string id)
  741. {
  742. var trunk = await _trunkIvrManagerRepository.GetAsync(id, HttpContext.RequestAborted);
  743. if (trunk is null)
  744. throw UserFriendlyException.SameMessage("无效线路");
  745. return trunk;
  746. }
  747. /// <summary>
  748. /// 新增线路
  749. /// </summary>
  750. /// <param name="dto"></param>
  751. /// <returns></returns>
  752. [HttpPost("addtrunk")]
  753. public async Task AddTrunk([FromBody] AddTrunkDto dto)
  754. {
  755. var trunk = _mapper.Map<TrunkIvrManager>(dto);
  756. await _trunkIvrManagerRepository.AddAsync(trunk, HttpContext.RequestAborted);
  757. }
  758. /// <summary>
  759. /// 修改线路
  760. /// </summary>
  761. /// <param name="dto"></param>
  762. /// <returns></returns>
  763. [HttpPost("updatetrunk")]
  764. public async Task UpdateTrunk([FromBody] UpdateTrunkDto dto)
  765. {
  766. var trunk = await _trunkIvrManagerRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  767. if (trunk is null)
  768. throw UserFriendlyException.SameMessage("无效线路");
  769. _mapper.Map(dto, trunk);
  770. await _trunkIvrManagerRepository.UpdateAsync(trunk, HttpContext.RequestAborted);
  771. }
  772. /// <summary>
  773. /// 删除线路
  774. /// </summary>
  775. /// <param name="id"></param>
  776. /// <returns></returns>
  777. [HttpGet("removetrunk/{id}")]
  778. public async Task RemoveTrunk(string id)
  779. {
  780. var trunk = await _trunkIvrManagerRepository.GetAsync(id, HttpContext.RequestAborted);
  781. if (trunk is null)
  782. throw UserFriendlyException.SameMessage("无效线路");
  783. await _trunkIvrManagerRepository.RemoveAsync(id, false, HttpContext.RequestAborted);
  784. }
  785. /// <summary>
  786. /// 线路页面基础信息
  787. /// </summary>
  788. /// <returns></returns>
  789. [HttpGet("trunk-page-info")]
  790. public async Task<object> TrunkPageInfo()
  791. {
  792. var ivr = await _ivrCategoryRepository.QueryAsync();
  793. var group = await _telGroupRepository.QueryAsync();
  794. var workDay = new List<WorkDayModel>();
  795. workDay.Add(new WorkDayModel() { weekName = "星期日", weekValue = "0" });
  796. workDay.Add(new WorkDayModel() { weekName = "星期一", weekValue = "1" });
  797. workDay.Add(new WorkDayModel() { weekName = "星期二", weekValue = "2" });
  798. workDay.Add(new WorkDayModel() { weekName = "星期三", weekValue = "3" });
  799. workDay.Add(new WorkDayModel() { weekName = "星期四", weekValue = "4" });
  800. workDay.Add(new WorkDayModel() { weekName = "星期五", weekValue = "5" });
  801. workDay.Add(new WorkDayModel() { weekName = "星期六", weekValue = "6" });
  802. return new { WorkCategorys = ivr, RestCategory = ivr, WorkToGroup = group, RestToGroup = group, WorkDay = workDay };
  803. }
  804. #endregion
  805. #region 话机业务
  806. /// <summary>
  807. /// 语音评价
  808. /// </summary>
  809. /// <param name="callId"></param>
  810. /// <returns></returns>
  811. [HttpGet("evaluate/{callId}")]
  812. public async Task Evaluate(string callId)
  813. {
  814. //检查通话是否存在
  815. var call = await _callRepository.GetAsync(callId, HttpContext.RequestAborted);
  816. if (call is null)
  817. {
  818. throw new UserFriendlyException("未找到当前通话");
  819. }
  820. if (call.CallDirection != ECallDirection.In)
  821. {
  822. throw new UserFriendlyException("当前通话不是来电,不能发送评价邀请");
  823. }
  824. if (call.CallStatus == ECallStatus.Bye)
  825. {
  826. throw new UserFriendlyException("当前通话已结束");
  827. }
  828. if (call.CallStatus != ECallStatus.Answered && call.CallStatus != ECallStatus.Answer)
  829. {
  830. throw new UserFriendlyException("当前未进行通话,不能发送评价邀请");
  831. }
  832. //获取配置
  833. var correct = _ivrDomainService.GetCorrectIvr(call.ToNo, true);
  834. if (correct is null)
  835. throw new UserFriendlyException("系统未配置评价,请联系管理员");
  836. //检查是否有评价录音配置
  837. var ivrList = await _ivrCacheManager.GetIvrsAsync(HttpContext.RequestAborted);
  838. if (!ivrList.Any())
  839. throw new UserFriendlyException("未查到任何ivr配置");
  840. var ivr = ivrList.First(x => x.IvrCategoryId == correct.ReturnValue && x.IsRoot);
  841. _logger.LogInformation("transfer to ivr.no:{ivrNo}", ivr.No);
  842. //写入子表
  843. var detail = new CallDetail()
  844. {
  845. CallId = call.Id,
  846. CallStatus = ECallStatus.Evaluate,
  847. ConversationId = call.ConversationId,
  848. EventName = "EVALUATE",
  849. FromNo = call.FromNo,
  850. ToNo = call.ToNo,
  851. };
  852. await _callDetailRepository.AddAsync(detail, HttpContext.RequestAborted);
  853. await _newRockDeviceManager.VisitorToMenuAsync(_options.Value.NewRock, call.ConversationId, ivr.No, HttpContext.RequestAborted);
  854. }
  855. #endregion
  856. #region 威尔信分机和分机组操作
  857. /// <summary>
  858. /// 查询分机
  859. /// </summary>
  860. /// <param name="dto"></param>
  861. /// <returns></returns>
  862. [HttpGet("query-tel-list")]
  863. public async Task<PagedDto<TelListPageDto>> QueryTelList([FromQuery] QueryTelListDto dto)
  864. {
  865. var rsp = await _wexClient.QueryTelsPageAsync(new QueryTelPageRequest() { PageIndex = dto.PageIndex, PageSize = dto.PageSize, input = new Input() { TelNo = dto.TelNo } }, HttpContext.RequestAborted);
  866. var telList = rsp?.Data;
  867. var count = rsp.Count;
  868. if (telList != null)
  869. {
  870. var telGroup = _wexTelGroupRepository.Queryable().ToList();
  871. var list = (from a in telList
  872. join b in telGroup on a.TelNo equals b.TelNo into output
  873. from j in output.DefaultIfEmpty()
  874. select new TelListPageDto
  875. {
  876. Id = (j == null ? "" : j.Id),
  877. TelNo = a.TelNo,
  878. GroupName = (j == null ? "" : j.GroupName),
  879. GroupId = (j == null ? 0 : j.GroupId)
  880. }).ToList();
  881. return new PagedDto<TelListPageDto>(count, list);
  882. }
  883. return new PagedDto<TelListPageDto>(0, null);
  884. }
  885. /// <summary>
  886. /// 新增或修改分机关联分机组
  887. /// </summary>
  888. /// <param name="dto"></param>
  889. /// <returns></returns>
  890. [HttpPost("add-update-telgroup")]
  891. public async Task AddOrUpdateTelGroup([FromBody] AddOrUpdateTelGroupDto dto)
  892. {
  893. if (string.IsNullOrEmpty(dto.Id))
  894. {
  895. //新增
  896. var telGroup = new WexTelGroup();
  897. telGroup.TelNo = dto.TelNo;
  898. telGroup.GroupId = dto.GroupId;
  899. telGroup.GroupName = dto.GroupName;
  900. telGroup.ZuoGroupName = dto.ZuoGroupName;
  901. await _wexTelGroupRepository.AddAsync(telGroup, HttpContext.RequestAborted);
  902. }
  903. else
  904. {
  905. //修改
  906. var telGroup = await _wexTelGroupRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  907. if (telGroup is null)
  908. {
  909. throw UserFriendlyException.SameMessage("未找到对应数据,无法修改");
  910. }
  911. if (dto.GroupId == 0)
  912. {
  913. await _wexTelGroupRepository.RemoveAsync(dto.Id, false, HttpContext.RequestAborted);
  914. }
  915. else
  916. {
  917. telGroup.GroupId = dto.GroupId;
  918. telGroup.GroupName = dto.GroupName;
  919. telGroup.ZuoGroupName = dto.ZuoGroupName;
  920. await _wexTelGroupRepository.UpdateAsync(telGroup);
  921. }
  922. }
  923. }
  924. /// <summary>
  925. /// 分机组列表
  926. /// </summary>
  927. /// <returns></returns>
  928. [HttpGet("telgroup-list")]
  929. public async Task<List<WexTelGroupDto>> TelGroupList()
  930. {
  931. var rsp = await _wexClient.QueryGroupAsync(new QueryGroupRequest() { }, HttpContext.RequestAborted);
  932. var groupList = rsp.Data;
  933. var list = _mapper.Map<List<WexTelGroupDto>>(groupList);
  934. return list;
  935. }
  936. /// <summary>
  937. /// 根据分机号查询分机关联坐席组
  938. /// </summary>
  939. /// <param name="telno"></param>
  940. /// <returns></returns>
  941. [HttpGet("telgroup/{telno}")]
  942. public async Task<WexTelGroup> TelGroup(string telno)
  943. {
  944. var telGroup = await _wexTelGroupRepository.GetAsync(x => x.TelNo == telno, HttpContext.RequestAborted);
  945. if (telGroup is null)
  946. {
  947. return new WexTelGroup() { TelNo = telno, };
  948. }
  949. return telGroup;
  950. }
  951. #endregion
  952. }
  953. }