PbxController.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. using Hotline.Application.FlowEngine;
  2. using Hotline.Caching.Interfaces;
  3. using Hotline.CallCenter.Calls;
  4. using Hotline.CallCenter.Ivrs;
  5. using Hotline.CallCenter.Tels;
  6. using Hotline.Permissions;
  7. using Hotline.Settings;
  8. using Hotline.Share.Dtos.CallCenter;
  9. using Hotline.Share.Dtos.FlowEngine;
  10. using Hotline.Share.Dtos.Trunk;
  11. using Hotline.Share.Enums.CallCenter;
  12. using Hotline.Share.Requests;
  13. using Hotline.Users;
  14. using MapsterMapper;
  15. using Microsoft.AspNetCore.Mvc;
  16. using SqlSugar;
  17. using Wex.Sdk;
  18. using Wex.Sdk.Tel;
  19. using XF.Domain.Authentications;
  20. using XF.Domain.Cache;
  21. using XF.Domain.Constants;
  22. using XF.Domain.Exceptions;
  23. using XF.Utility.EnumExtensions;
  24. using System.Linq;
  25. using Hotline.CallCenter.Configs;
  26. using Hotline.CallCenter.Devices;
  27. using Hotline.FlowEngine.WorkflowModules;
  28. using Hotline.NewRock;
  29. using Hotline.Share.Dtos;
  30. using Microsoft.AspNetCore.Authorization;
  31. using Microsoft.Extensions.Options;
  32. using XF.Domain.Repository;
  33. using Tr.Sdk;
  34. using Hotline.Configurations;
  35. namespace Hotline.Api.Controllers
  36. {
  37. /// <summary>
  38. /// 话机设备管理
  39. /// </summary>
  40. public class PbxController : BaseController
  41. {
  42. private readonly ITelRepository _telRepository;
  43. private readonly ITelRestRepository _telRestRepository;
  44. private readonly ITelDomainService _telDomainService;
  45. private readonly ITypedCache<Tel> _cacheTel;
  46. private readonly ITypedCache<TelGroup> _cacheTelGroup;
  47. private readonly ITelGroupRepository _telGroupRepository;
  48. private readonly IMapper _mapper;
  49. private readonly IWorkRepository _workRepository;
  50. private readonly INewRockDeviceManager _newRockDeviceManager;
  51. private readonly IUserCacheManager _userCacheManager;
  52. private readonly ISessionContext _sessionContext;
  53. private readonly ICallRepository _callRepository;
  54. private readonly IRepository<TrunkIvrManager> _trunkIvrManagerRepository;
  55. private readonly IIvrCategoryRepository _ivrCategoryRepository;
  56. private readonly IWorkflowApplication _workflowApplication;
  57. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  58. private readonly IIvrDomainService _ivrDomainService;
  59. private readonly IIvrCacheManager _ivrCacheManager;
  60. private readonly ILogger<TelController> _logger;
  61. private readonly ICallDetailRepository _callDetailRepository;
  62. private readonly IRepository<User> _userRepository;
  63. private readonly IWexClient _wexClient;
  64. private readonly IWexTelGroupRepository _wexTelGroupRepository;
  65. private readonly IOptionsSnapshot<CallCenterConfiguration> _options;
  66. private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
  67. public PbxController(
  68. IServiceProvider serviceProvider,
  69. ITelRepository telRepository,
  70. ITelRestRepository telRestRepository,
  71. ITelDomainService telDomainService,
  72. ITypedCache<Tel> cacheTel,
  73. ITypedCache<TelGroup> cacheTelGroup,
  74. ITelGroupRepository telGroupRepository,
  75. IMapper mapper,
  76. IWorkRepository workRepository,
  77. IUserCacheManager userCacheManager,
  78. ISessionContext sessionContext,
  79. ICallRepository callRepository,
  80. IRepository<TrunkIvrManager> trunkIvrManagerRepository,
  81. IIvrCategoryRepository ivrCategoryRepository,
  82. IWorkflowApplication workflowApplication,
  83. ISystemSettingCacheManager systemSettingCacheManager,
  84. IIvrDomainService ivrDomainService,
  85. IIvrCacheManager ivrCacheManager,
  86. ILogger<TelController> logger,
  87. ICallDetailRepository callDetailRepository,
  88. IRepository<User> userRepository,
  89. IWexClient wexClient,
  90. IWexTelGroupRepository wexTelGroupRepository,
  91. IOptionsSnapshot<AppConfiguration> appOptions,
  92. IOptionsSnapshot<CallCenterConfiguration> options,
  93. ISystemDicDataCacheManager systemDicDataCacheManager)
  94. {
  95. _telRepository = telRepository;
  96. _telRestRepository = telRestRepository;
  97. _telDomainService = telDomainService;
  98. _cacheTel = cacheTel;
  99. _cacheTelGroup = cacheTelGroup;
  100. _telGroupRepository = telGroupRepository;
  101. _mapper = mapper;
  102. _workRepository = workRepository;
  103. _userCacheManager = userCacheManager;
  104. _sessionContext = sessionContext;
  105. _callRepository = callRepository;
  106. _trunkIvrManagerRepository = trunkIvrManagerRepository;
  107. _ivrCategoryRepository = ivrCategoryRepository;
  108. _workflowApplication = workflowApplication;
  109. _systemSettingCacheManager = systemSettingCacheManager;
  110. _ivrDomainService = ivrDomainService;
  111. _ivrCacheManager = ivrCacheManager;
  112. _logger = logger;
  113. _callDetailRepository = callDetailRepository;
  114. _userRepository = userRepository;
  115. _wexClient = wexClient;
  116. _wexTelGroupRepository = wexTelGroupRepository;
  117. _options = options;
  118. _systemDicDataCacheManager = systemDicDataCacheManager;
  119. if (appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XunShi)
  120. {
  121. _newRockDeviceManager = serviceProvider.GetRequiredService<INewRockDeviceManager>();
  122. }
  123. }
  124. #region 话机
  125. /// <summary>
  126. /// 根据设备自动同步分机数据到数据库
  127. /// </summary>
  128. /// <returns></returns>
  129. [HttpPut("sync-tels")]
  130. public async Task SyncTelsAsync()
  131. {
  132. var dbTels = await _telRepository.QueryAsync();
  133. foreach (var dbTel in dbTels)
  134. {
  135. _cacheTel.Remove(dbTel.No);
  136. }
  137. //await _telRepository.RemoveRangeAsync(dbTels);
  138. var tels = await _telDomainService.QueryTelsAsync(HttpContext.RequestAborted);
  139. var list = tels.ExceptBy(dbTels.Select(e => e.No), x => x.No).ToList();
  140. var delList = dbTels.ExceptBy(tels.Select(e => e.No), x => x.No).ToList();
  141. for (int i = 0; i < delList.Count; i++)
  142. {
  143. delList[i].SoftDelete();
  144. }
  145. await _telRepository.UpdateRangeAsync(delList);
  146. await _telRepository.AddRangeAsync(list);
  147. }
  148. /// <summary>
  149. /// 查询所有分机
  150. /// </summary>
  151. /// <returns></returns>
  152. [HttpGet("query-tels")]
  153. public async Task<IReadOnlyList<TelDto>> QueryTels()
  154. {
  155. var tels = await _telRepository.QueryExtAsync(d => true, d => d.Includes(x => x.Groups));
  156. return _mapper.Map<IReadOnlyList<TelDto>>(tels);
  157. }
  158. #endregion
  159. #region 分机组
  160. /// <summary>
  161. /// 页面基础信息
  162. /// </summary>
  163. /// <returns></returns>
  164. [HttpGet("base-info-group")]
  165. public async Task<dynamic> GetBaseInfoGroup()
  166. {
  167. return new
  168. {
  169. Distributions = EnumExts.GetDescriptions<EDistribution>()
  170. };
  171. }
  172. /// <summary>
  173. /// 查询所有分机组
  174. /// </summary>
  175. /// <returns></returns>
  176. [HttpGet("query-telgroups")]
  177. public async Task<IReadOnlyList<TelGroupDto>> QueryTelGroups()
  178. {
  179. var groups = await _telGroupRepository.QueryExtAsync(d => true, d => d.Includes(x => x.Tels));
  180. return _mapper.Map<IReadOnlyList<TelGroupDto>>(groups);
  181. }
  182. /// <summary>
  183. /// 新增分机组
  184. /// </summary>
  185. /// <param name="dto"></param>
  186. /// <returns></returns>
  187. [HttpPost("add-telgroup")]
  188. public async Task AddTelGroup([FromBody] AddTelGroupDto dto)
  189. {
  190. var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
  191. await _newRockDeviceManager.AssginConfigGroupAsync(
  192. _options.Value.NewRock, dto.No,
  193. dto.Distribution,
  194. ext: works.Select(d => d.TelNo).ToList(),
  195. voiceFile: dto.Voice ?? null,
  196. cancellationToken: HttpContext.RequestAborted);
  197. var group = _mapper.Map<TelGroup>(dto);
  198. var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
  199. group.Tels = tels;
  200. await _telGroupRepository.AddNavTelsAsync(group, HttpContext.RequestAborted);
  201. _cacheTelGroup.Remove(dto.No);
  202. }
  203. /// <summary>
  204. /// 更新分机组
  205. /// </summary>
  206. /// <param name="dto"></param>
  207. /// <returns></returns>
  208. [HttpPut("update-telgroup")]
  209. public async Task UpdateTelGroup([FromBody] UpdateTelGroupDto dto)
  210. {
  211. var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
  212. await _newRockDeviceManager.AssginConfigGroupAsync(
  213. _options.Value.NewRock, dto.No,
  214. dto.Distribution,
  215. ext: works.Select(d => d.TelNo).ToList(),
  216. voiceFile: dto.Voice ?? null,
  217. cancellationToken: HttpContext.RequestAborted);
  218. var group = _mapper.Map<TelGroup>(dto);
  219. var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
  220. group.Tels = tels;
  221. await _telGroupRepository.UpdateNavTelsAsync(group, HttpContext.RequestAborted);
  222. _cacheTelGroup.Remove(dto.No);
  223. }
  224. #endregion
  225. #region 话机设备操作
  226. /// <summary>
  227. /// 查询小休流程开启参数
  228. /// </summary>
  229. /// <returns></returns>
  230. [HttpGet("flow-start")]
  231. public async Task<NextStepsDto> GetFlowStartOptionsAsync()
  232. {
  233. //return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.TelRestApply,
  234. // HttpContext.RequestAborted);
  235. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.TelRestApply,
  236. HttpContext.RequestAborted);
  237. }
  238. /// <summary>
  239. /// 分机休息
  240. /// </summary>
  241. /// <returns></returns>
  242. [HttpPost("rest")]
  243. public async Task Rest([FromBody] StartRestDto dto)
  244. {
  245. var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
  246. if (work is null)
  247. throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
  248. bool isCanApply = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsRestApproval).SettingValue[0]);
  249. if (isCanApply)
  250. {
  251. var isApply = await _telRestRepository.IsApplyingAsync(work.TelNo, HttpContext.RequestAborted);
  252. if (isApply)
  253. throw new UserFriendlyException("分机休息申请正在审核阶段");
  254. }
  255. var isResting = await _telRestRepository.IsRestingAsync(work.TelNo, HttpContext.RequestAborted);
  256. if (isResting)
  257. throw new UserFriendlyException("当前坐席正在休息");
  258. var user = _userRepository.Get(work.UserId);
  259. var telRest = new TelRest(work.TelId, work.TelNo, work.UserId, work.UserName, dto.Reason, isCanApply, user.StaffNo);
  260. await _telRestRepository.AddAsync(telRest, HttpContext.RequestAborted);
  261. if (!isCanApply)
  262. {
  263. await _telDomainService.TelRestApplyPassAsync(telRest.Id, HttpContext.RequestAborted);
  264. }
  265. else
  266. {
  267. var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
  268. startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
  269. startWorkflowDto.Opinion = dto.Reason;
  270. startWorkflowDto.Title = "分机休息申请流程";
  271. await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, telRest.Id, cancellationToken: HttpContext.RequestAborted);
  272. }
  273. }
  274. #region 威尔信小休
  275. /// <summary>
  276. /// 分机休息流程开始
  277. /// </summary>
  278. /// <param name="dto"></param>
  279. /// <returns></returns>
  280. [HttpPost("rest-flow")]
  281. public async Task RestFlow([FromBody] StartRestDto dto)
  282. {
  283. var tel = await _wexClient.QueryTelsAsync(new QueryTelRequest() { StaffNo = _sessionContext.StaffNo }, HttpContext.RequestAborted);
  284. if (tel.Data == null || tel.Data.Count == 0)
  285. throw UserFriendlyException.SameMessage("未找到分机信息");
  286. if (tel.Data[0].Sigin == 0)
  287. throw UserFriendlyException.SameMessage("分机未签入,不能休息");
  288. var isApply = await _telRestRepository.IsApplyingAsync(tel.Data[0].TelNo, HttpContext.RequestAborted);
  289. if (isApply)
  290. throw UserFriendlyException.SameMessage("分机休息申请正在审核阶段");
  291. var isResting = await _telRestRepository.IsRestingAsync(tel.Data[0].TelNo, HttpContext.RequestAborted);
  292. if (isResting)
  293. throw new UserFriendlyException("当前坐席正在休息");
  294. var telRest = new TelRest(tel.Data[0].TelNo, tel.Data[0].TelNo, _sessionContext.RequiredUserId, _sessionContext.UserName, dto.Reason, true, _sessionContext.StaffNo);
  295. await _telRestRepository.AddAsync(telRest, HttpContext.RequestAborted);
  296. var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
  297. startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
  298. startWorkflowDto.Opinion = dto.Reason;
  299. startWorkflowDto.Title = "分机休息申请流程";
  300. await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, 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. }