QualityController.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. using Hotline.Caching.Interfaces;
  2. using MapsterMapper;
  3. using XF.Domain.Authentications;
  4. using XF.Domain.Repository;
  5. using Hotline.Quality;
  6. using Hotline.Permissions;
  7. using Hotline.Repository.SqlSugar.Extensions;
  8. using Hotline.Settings;
  9. using Hotline.Share.Dtos;
  10. using Microsoft.AspNetCore.Mvc;
  11. using XF.Domain.Exceptions;
  12. using Hotline.Share.Dtos.Quality;
  13. using Hotline.Share.Enums.Quality;
  14. using XF.Utility.EnumExtensions;
  15. using Hotline.Application.Quality;
  16. using Microsoft.AspNetCore.Authorization;
  17. using Hotline.Orders;
  18. using Hotline.Ai.Quality;
  19. using Hotline.Api.Filter;
  20. using Hotline.Application.CallCenter;
  21. using Hotline.CallCenter.Configs;
  22. using Microsoft.Extensions.Options;
  23. using Hotline.Configurations;
  24. using Hotline.CallCenter.Calls;
  25. using System.Linq;
  26. using Hotline.Repository.SqlSugar.Quality;
  27. namespace Hotline.Api.Controllers
  28. {
  29. public class QualityController : BaseController
  30. {
  31. private readonly ISessionContext _sessionContext;
  32. private readonly IMapper _mapper;
  33. private readonly IQualityRepository _qualitey;
  34. private readonly IRepository<QualityDetail> _qualiteyDetail;
  35. private readonly IRepository<QualityItem> _qualiteyItem;
  36. private readonly IRepository<QualityTemplate> _qualityTemplate;
  37. private readonly IRepository<QualityTemplateDetail> _qualiteyTemplateDetail;
  38. private readonly IRepository<QualityProhibited> _qualiteyProhibited;
  39. private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
  40. //private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  41. private readonly IQualityApplication _qualityApplication;
  42. private readonly IOrderRepository _orderRepository;
  43. private readonly IServiceProvider _serviceProvider;
  44. //private readonly IAiQualityService _aiQualityService;
  45. private readonly ILogger<QualityController> _logger;
  46. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  47. private readonly ICallApplication _callApplication;
  48. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  49. private readonly IRepository<SystemLog> _logRepository;
  50. private readonly IRepository<QualityTransferRecords> _qualityTransferRecordsRepository;
  51. public QualityController(
  52. ISessionContext sessionContext,
  53. IMapper mapper,
  54. IQualityRepository qualitey,
  55. IRepository<Quality.QualityDetail> qualiteyDetail,
  56. IRepository<QualityItem> qualiteyItem,
  57. IRepository<QualityTemplate> qualityTemplate,
  58. IRepository<QualityTemplateDetail> qualiteyTemplateDetail,
  59. IRepository<QualityProhibited> qualiteyProhibited,
  60. ISystemDicDataCacheManager systemDicDataCacheManager,
  61. //IRepository<TrCallRecord> trCallRecordRepository,
  62. IQualityApplication qualityApplication,
  63. IOrderRepository orderRepository,
  64. //IAiQualityService aiQualityService,
  65. IServiceProvider serviceProvider,
  66. ILogger<QualityController> logger,
  67. ISystemSettingCacheManager systemSettingCacheManager,
  68. ICallApplication callApplication,
  69. IOptionsSnapshot<AppConfiguration> appOptions,
  70. IRepository<SystemLog> logRepository,
  71. IRepository<QualityTransferRecords> qualityTransferRecordsRepository)
  72. {
  73. _sessionContext = sessionContext;
  74. _mapper = mapper;
  75. _qualitey = qualitey;
  76. _qualiteyDetail = qualiteyDetail;
  77. _qualiteyItem = qualiteyItem;
  78. _qualityTemplate = qualityTemplate;
  79. _qualiteyTemplateDetail = qualiteyTemplateDetail;
  80. _qualiteyProhibited = qualiteyProhibited;
  81. _systemDicDataCacheManager = systemDicDataCacheManager;
  82. //_trCallRecordRepository = trCallRecordRepository;
  83. _qualityApplication = qualityApplication;
  84. _orderRepository = orderRepository;
  85. _serviceProvider = serviceProvider;
  86. //_aiQualityService = aiQualityService;
  87. _logger = logger;
  88. _systemSettingCacheManager = systemSettingCacheManager;
  89. _callApplication = callApplication;
  90. _appOptions = appOptions;
  91. _logRepository = logRepository;
  92. _qualityTransferRecordsRepository = qualityTransferRecordsRepository;
  93. }
  94. #region 质检管理
  95. /// <summary>
  96. /// 删除质检
  97. /// </summary>
  98. /// <param name="dto"></param>
  99. /// <returns></returns>
  100. [HttpDelete]
  101. public async Task Delete([FromBody] DeleteQualityDto dto)
  102. {
  103. foreach (var Id in dto.Ids)
  104. {
  105. await _qualitey.RemoveAsync(x => x.Id == Id);
  106. List<QualityDetail> details = await _qualiteyDetail.Queryable().Where(x => x.QualityId == Id).ToListAsync();
  107. await _qualiteyDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  108. }
  109. }
  110. /// <summary>
  111. /// 更新质检
  112. /// </summary>
  113. /// <param name="dto"></param>
  114. /// <returns></returns>
  115. [HttpPut]
  116. public async Task Update([FromBody] UpdateQualityDto dto)
  117. {
  118. await _qualityApplication.UpdateQualityAsync(dto, HttpContext.RequestAborted);
  119. }
  120. /// <summary>
  121. /// 更新质检
  122. /// </summary>
  123. /// <param name="dto"></param>
  124. /// <returns></returns>
  125. [HttpPut("transfer")]
  126. public async Task TransferUpdate([FromBody] TransferUpdate dto)
  127. {
  128. await _qualitey.Updateable().SetColumns(x=> new Hotline.Quality.Quality { Transfer = dto.Transfer }).Where(x=>x.Id == dto.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
  129. }
  130. /// <summary>
  131. /// 获取质检列表
  132. /// </summary>
  133. /// <param name="dto"></param>
  134. /// <returns></returns>
  135. [HttpGet("list")]
  136. public async Task<PagedDto<QualityDto>> List([FromQuery] QualityListDto dto)
  137. {
  138. var (total, items) = await _qualitey.Queryable()
  139. .Includes(x => x.Order)
  140. .Includes(x => x.Visit)
  141. .Includes(x => x.Visit, e => e.Employee)
  142. .Includes(x => x.QualityDetails)
  143. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
  144. .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
  145. .WhereIF(dto.State.HasValue, x => x.State == dto.State)
  146. .WhereIF(dto.Source.HasValue, x => x.Source == dto.Source)
  147. .WhereIF(dto.Source.HasValue && dto.Source == EQualitySource.Accepted, x => !string.IsNullOrEmpty(x.Order.CallId))
  148. .WhereIF(dto.Source.HasValue && dto.Source == EQualitySource.Visit, x => !string.IsNullOrEmpty(x.Visit.CallId))
  149. .WhereIF(dto.CreationTimeStart.HasValue, x => x.CreationTime >= dto.CreationTimeStart)
  150. .WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
  151. .WhereIF(dto.MaxGrade.HasValue, x => x.Grade <= dto.MaxGrade)
  152. .WhereIF(dto.MinGrade.HasValue, x => x.Grade >= dto.MinGrade)
  153. .OrderByDescending(x => x.CreationTime)
  154. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  155. return new PagedDto<QualityDto>(total, _mapper.Map<IReadOnlyList<QualityDto>>(items));
  156. }
  157. /// <summary>
  158. /// 获取质检实体
  159. /// </summary>
  160. /// <param name="id"></param>
  161. /// <returns></returns>
  162. [HttpGet("{id}")]
  163. public async Task<QualityDto> Entity(string id)
  164. {
  165. var quality = await _qualitey.Queryable()
  166. .Includes(x => x.Order)
  167. .Includes(x => x.Visit)
  168. .Includes(x => x.Visit, e => e.Employee)
  169. .Includes(x => x.QualityDetails)
  170. .FirstAsync(x => x.Id == id);
  171. var qualityDto = _mapper.Map<QualityDto>(quality);
  172. // if (qualityDto.Order != null) {
  173. // //var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Order.CallId).FirstAsync(); //由CallAccept改为OtherAccept
  174. // var call = await _trCallRecordRepository.Queryable().Where(x => x.OtherAccept == qualityDto.Order.CallId).FirstAsync();
  175. // if (call != null)
  176. // {
  177. // qualityDto.Order.RecordingBaseAddress = call.RecordingBaseAddress;
  178. // qualityDto.Order.RecordingAbsolutePath = call.RecordingAbsolutePath;
  179. // }
  180. // }
  181. // if (qualityDto.Visit != null)
  182. // {
  183. // //var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Visit.CallId).FirstAsync(); //由CallAccept改为OtherAccept
  184. // var call = await _trCallRecordRepository.Queryable().Where(x => x.OtherAccept == qualityDto.Visit.CallId).FirstAsync();
  185. // if (call != null)
  186. // {
  187. // qualityDto.Visit.RecordingBaseAddress = call.RecordingBaseAddress;
  188. // qualityDto.Visit.RecordingAbsolutePath = call.RecordingAbsolutePath;
  189. // }
  190. // }
  191. if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
  192. {
  193. if (qualityDto.Order != null)
  194. {
  195. //var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Order.CallId).FirstAsync(); //由CallAccept改为OtherAccept
  196. //var call = await _trCallRecordRepository.Queryable().Where(x => x.OtherAccept == qualityDto.Order.CallId).FirstAsync();
  197. var call = await _callApplication.GetTianrunCallAsync(qualityDto.Order.CallId, HttpContext.RequestAborted);
  198. if (call != null)
  199. {
  200. qualityDto.Order.RecordingBaseAddress = call.RecordingBaseAddress;
  201. qualityDto.Order.RecordingAbsolutePath = call.RecordingAbsolutePath;
  202. }
  203. }
  204. if (qualityDto.Visit != null)
  205. {
  206. //var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Visit.CallId).FirstAsync(); //由CallAccept改为OtherAccept
  207. // var call = await _trCallRecordRepository.Queryable().Where(x => x.OtherAccept == qualityDto.Visit.CallId).FirstAsync();
  208. var call = await _callApplication.GetTianrunCallAsync(qualityDto.Visit.CallId, HttpContext.RequestAborted);
  209. if (call != null)
  210. {
  211. qualityDto.Visit.RecordingBaseAddress = call.RecordingBaseAddress;
  212. qualityDto.Visit.RecordingAbsolutePath = call.RecordingAbsolutePath;
  213. }
  214. }
  215. }
  216. else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
  217. {
  218. if (!string.IsNullOrEmpty(qualityDto?.Order?.CallId))
  219. {
  220. var call = await _callApplication.GetCallAsync(qualityDto.Order.CallId, HttpContext.RequestAborted);
  221. if (call != null)
  222. {
  223. qualityDto.Order.RecordingBaseAddress = call.AudioFile;
  224. qualityDto.Order.RecordingAbsolutePath = call.AudioFile;
  225. }
  226. }
  227. if (!string.IsNullOrEmpty(qualityDto?.Visit?.CallId))
  228. {
  229. var call = await _callApplication.GetCallAsync(qualityDto.Visit.CallId, HttpContext.RequestAborted);
  230. if (call != null)
  231. {
  232. qualityDto.Visit.RecordingBaseAddress = call.AudioFile;
  233. qualityDto.Visit.RecordingAbsolutePath = call.AudioFile;
  234. }
  235. }
  236. }
  237. return qualityDto;
  238. }
  239. #endregion
  240. #region 质检项管理
  241. /// <summary>
  242. /// 新增项目
  243. /// </summary>
  244. /// <param name="dtos"></param>
  245. /// <returns></returns>
  246. [HttpPost("item")]
  247. public async Task Add([FromBody] QualityItemAddDto dto)
  248. {
  249. var count = await _qualiteyItem.CountAsync(x => x.Name == dto.Name);
  250. if (count > 0)
  251. throw UserFriendlyException.SameMessage("质检项目名称已存在");
  252. var model = _mapper.Map<QualityItem>(dto);
  253. await _qualiteyItem.AddAsync(model, HttpContext.RequestAborted);
  254. }
  255. ///// <summary>
  256. ///// 删除项目
  257. ///// </summary>
  258. ///// <param name="dto"></param>
  259. ///// <returns></returns>
  260. //[HttpDelete("item")]
  261. //public async Task Delete([FromBody] QualityItemDeleteDto dto)
  262. //{
  263. // await _qualiteyItem.RemoveAsync(x => x.Id == dto.Id);
  264. //}
  265. /// <summary>
  266. /// 删除项目
  267. /// </summary>
  268. /// <param name="dto"></param>
  269. /// <returns></returns>
  270. [HttpDelete("itemBatch")]
  271. public async Task Delete([FromBody] QualityItemBatchDeleteDto dto)
  272. {
  273. List<QualityItem> items = await _qualiteyItem.Queryable().In(x => x.Id, dto.Ids).ToListAsync();
  274. foreach (var item in items)
  275. {
  276. var detail = await _qualiteyDetail.Queryable().Where(x => x.Name == item.Name).AnyAsync();
  277. //质检中已存在不可以删
  278. if (detail) items.Remove(item);
  279. }
  280. if (items.Any())
  281. {
  282. await _qualiteyItem.RemoveRangeAsync(items, true, HttpContext.RequestAborted);
  283. var tempItems = await _qualiteyTemplateDetail.Queryable().In(x => x.ItemId, items.Select(x => x.Id)).ToListAsync(HttpContext.RequestAborted);
  284. if (tempItems.Any()) await _qualiteyTemplateDetail.RemoveRangeAsync(tempItems, HttpContext.RequestAborted);
  285. }
  286. }
  287. /// <summary>
  288. /// 更新项目
  289. /// </summary>
  290. /// <param name="dto"></param>
  291. /// <returns></returns>
  292. [HttpPut("item")]
  293. public async Task Update([FromBody] QualityItemUpdateDto dto)
  294. {
  295. var item = await _qualiteyItem.GetAsync(dto.Id, HttpContext.RequestAborted);
  296. if (item is null)
  297. throw UserFriendlyException.SameMessage("无效质检项目");
  298. if (item.IsEnable != dto.IsEnable || item.Name != dto.Name)
  299. {
  300. var detail = await _qualiteyDetail.Queryable().Where(x => x.Name == item.Name && !x.IsDeleted).AnyAsync();
  301. if (detail) throw UserFriendlyException.SameMessage("质检项目在中心质检中已使用,不能修改状态和名称!");
  302. }
  303. _mapper.Map(dto, item);
  304. item.LastModificationName = _sessionContext.UserName;
  305. await _qualiteyItem.UpdateAsync(item, HttpContext.RequestAborted);
  306. }
  307. /// <summary>
  308. /// 获取项目列表
  309. /// </summary>
  310. /// <param name="dto"></param>
  311. /// <returns></returns>
  312. [HttpGet("item/list")]
  313. public async Task<PagedDto<QualityItemDto>> List([FromQuery] QualityItemListDto dto)
  314. {
  315. var (total, items) = await _qualiteyItem.Queryable()
  316. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  317. .WhereIF(!string.IsNullOrEmpty(dto.GroupingName), d => d.GroupingName.Contains(dto.GroupingName!))
  318. .WhereIF(dto.IsEnable.HasValue, d => d.IsEnable == dto.IsEnable)
  319. .OrderByDescending(x => x.CreationTime)
  320. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  321. return new PagedDto<QualityItemDto>(total, _mapper.Map<IReadOnlyList<QualityItemDto>>(items));
  322. }
  323. /// <summary>
  324. /// 获取项目实体
  325. /// </summary>
  326. /// <param name="id"></param>
  327. /// <returns></returns>
  328. [HttpGet("item/{id}")]
  329. public async Task<QualityItem> ItemEntity(string id)
  330. {
  331. return await _qualiteyItem.Queryable()
  332. .FirstAsync(x => x.Id == id);
  333. }
  334. #endregion
  335. #region 质检模版管理
  336. /// <summary>
  337. /// 新增模版
  338. /// </summary>
  339. /// <param name="dtos"></param>
  340. /// <returns></returns>
  341. [HttpPost("template")]
  342. public async Task Add([FromBody] TemplateAddDto dto)
  343. {
  344. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.IsEnable == 1);
  345. if (groupingCount > 0 && dto.IsEnable == 1)
  346. throw UserFriendlyException.SameMessage("当前已存在");
  347. var names = dto.TemplateDetails.Select(x => x.ItemId).ToList();
  348. var nameCount = names.GroupBy(x => x).Count(c => c.Count() > 1);
  349. if (nameCount > 0)
  350. throw UserFriendlyException.SameMessage("质检模版存在重复质检项");
  351. var model = _mapper.Map<QualityTemplate>(dto);
  352. var id = await _qualityTemplate.AddAsync(model, HttpContext.RequestAborted);
  353. if (!string.IsNullOrEmpty(id))
  354. {
  355. foreach (var item in dto.TemplateDetails)
  356. {
  357. item.TemplateId = id;
  358. }
  359. List<QualityTemplateDetail> details = _mapper.Map<List<QualityTemplateDetail>>(dto.TemplateDetails);
  360. await _qualiteyTemplateDetail.AddRangeAsync(details, HttpContext.RequestAborted);
  361. }
  362. }
  363. /// <summary>
  364. /// 删除模版
  365. /// </summary>
  366. /// <param name="dto"></param>
  367. /// <returns></returns>
  368. [HttpDelete("template")]
  369. public async Task Delete([FromBody] TemplateDeleteDto dto)
  370. {
  371. await _qualityTemplate.RemoveAsync(x => x.Id == dto.Id);
  372. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().Where(x => x.TemplateId == dto.Id).ToListAsync();
  373. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  374. }
  375. /// <summary>
  376. /// 删除模版
  377. /// </summary>
  378. /// <param name="dto"></param>
  379. /// <returns></returns>
  380. [HttpDelete("templateBatch")]
  381. public async Task Delete([FromBody] TemplateBatchDeleteDto dto)
  382. {
  383. List<QualityTemplate> templates = await _qualityTemplate.Queryable().In(x => x.Id, dto.Ids).ToListAsync();
  384. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().In(x => x.TemplateId, dto.Ids).ToListAsync();
  385. await _qualityTemplate.RemoveRangeAsync(templates, HttpContext.RequestAborted);
  386. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  387. }
  388. /// <summary>
  389. /// 更新模版
  390. /// </summary>
  391. /// <param name="dto"></param>
  392. /// <returns></returns>
  393. [HttpPut("template")]
  394. public async Task Update([FromBody] TemplateUpdateDto dto)
  395. {
  396. var template = await _qualityTemplate.GetAsync(dto.Id, HttpContext.RequestAborted);
  397. if (template is null)
  398. throw UserFriendlyException.SameMessage("无效质检模版");
  399. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.Id != dto.Id && x.IsEnable == 1);
  400. if (groupingCount > 0)
  401. throw UserFriendlyException.SameMessage("当前质检分类已存在");
  402. _mapper.Map(dto, template);
  403. template.LastModificationName = _sessionContext.UserName;
  404. await _qualityTemplate.UpdateAsync(template, HttpContext.RequestAborted);
  405. if (dto.TemplateDetails.Any())
  406. {
  407. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().Where(x => x.TemplateId == dto.Id).ToListAsync();
  408. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  409. foreach (var item in dto.TemplateDetails)
  410. {
  411. item.TemplateId = dto.Id;
  412. }
  413. List<QualityTemplateDetail> newDetails = _mapper.Map<List<QualityTemplateDetail>>(dto.TemplateDetails);
  414. await _qualiteyTemplateDetail.AddRangeAsync(newDetails, HttpContext.RequestAborted);
  415. }
  416. }
  417. /// <summary>
  418. /// 获取模版列表
  419. /// </summary>
  420. /// <param name="dto"></param>
  421. /// <returns></returns>
  422. [HttpGet("template/list")]
  423. public async Task<PagedDto<QualityTemplateDto>> List([FromQuery] TemplateListDto dto)
  424. {
  425. var (total, items) = await _qualityTemplate.Queryable()
  426. .Includes(x => x.templateDetails)
  427. .Includes(x => x.templateDetails, y => y.QualityItem)
  428. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  429. .WhereIF(dto.Grouping.HasValue, d => d.Grouping == dto.Grouping)
  430. .WhereIF(dto.IsEnable.HasValue, d => d.IsEnable == dto.IsEnable)
  431. .OrderByDescending(x => x.CreationTime)
  432. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  433. return new PagedDto<QualityTemplateDto>(total, _mapper.Map<IReadOnlyList<QualityTemplateDto>>(items));
  434. }
  435. /// <summary>
  436. /// 获取模版实体
  437. /// </summary>
  438. /// <param name="id"></param>
  439. /// <returns></returns>
  440. [HttpGet("template/{id}")]
  441. public async Task<QualityTemplateDto> TemplateEntity(string id)
  442. {
  443. var template = await _qualityTemplate.Queryable()
  444. .Includes(x => x.templateDetails)
  445. .Includes(x => x.templateDetails, y => y.QualityItem)
  446. .FirstAsync(x => x.Id == id);
  447. return _mapper.Map<QualityTemplateDto>(template);
  448. }
  449. /// <summary>
  450. /// 启禁用
  451. /// </summary>
  452. /// <param name="dto"></param>
  453. /// <returns></returns>
  454. [HttpPut("template/enable")]
  455. public async Task Enable([FromBody] TemplateUpdateDto dto)
  456. {
  457. var template = await _qualityTemplate.GetAsync(dto.Id, HttpContext.RequestAborted);
  458. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.Id != dto.Id && x.IsEnable == 1);
  459. if (groupingCount > 0)
  460. throw UserFriendlyException.SameMessage("当前质检分类已存在");
  461. if (template is null)
  462. throw UserFriendlyException.SameMessage("无效质检模版");
  463. _mapper.Map(dto, template);
  464. await _qualityTemplate.UpdateAsync(template, HttpContext.RequestAborted);
  465. }
  466. #endregion
  467. #region 质检词库管理
  468. /// <summary>
  469. /// 新增违禁词
  470. /// </summary>
  471. /// <param name="dtos"></param>
  472. /// <returns></returns>
  473. [HttpPost("prohibited")]
  474. public async Task Add([FromBody] ProhibitedAddDto dto)
  475. {
  476. var model = _mapper.Map<QualityProhibited>(dto);
  477. await _qualiteyProhibited.AddAsync(model, HttpContext.RequestAborted);
  478. }
  479. /// <summary>
  480. /// 删除违禁词
  481. /// </summary>
  482. /// <param name="dto"></param>
  483. /// <returns></returns>
  484. [HttpDelete("prohibited")]
  485. public async Task Delete([FromBody] ProhibitedDeleteDto dto)
  486. {
  487. await _qualiteyProhibited.RemoveAsync(x => x.Id == dto.Id);
  488. }
  489. /// <summary>
  490. /// 删除违禁词
  491. /// </summary>
  492. /// <param name="dto"></param>
  493. /// <returns></returns>
  494. [HttpDelete("prohibitedBatch")]
  495. public async Task Delete([FromBody] ProhibitedBatchDeleteDto dto)
  496. {
  497. List<QualityProhibited> prohibiteds = await _qualiteyProhibited.Queryable().In(x => x.Id, dto.Ids).ToListAsync();
  498. await _qualiteyProhibited.RemoveRangeAsync(prohibiteds, HttpContext.RequestAborted);
  499. }
  500. /// <summary>
  501. /// 更新违禁词
  502. /// </summary>
  503. /// <param name="dto"></param>
  504. /// <returns></returns>
  505. [HttpPut("prohibited")]
  506. public async Task Update([FromBody] ProhibitedUpdateDto dto)
  507. {
  508. var prohibited = await _qualiteyProhibited.GetAsync(dto.Id, HttpContext.RequestAborted);
  509. if (prohibited is null)
  510. throw UserFriendlyException.SameMessage("无效质检模版");
  511. _mapper.Map(dto, prohibited);
  512. prohibited.LastModificationName = _sessionContext.UserName;
  513. await _qualiteyProhibited.UpdateAsync(prohibited, HttpContext.RequestAborted);
  514. }
  515. /// <summary>
  516. /// 获取违禁词列表
  517. /// </summary>
  518. /// <param name="dto"></param>
  519. /// <returns></returns>
  520. [HttpGet("prohibited/list")]
  521. public async Task<PagedDto<QualityProhibitedDto>> List([FromQuery] ProhibitedListDto dto)
  522. {
  523. var (total, items) = await _qualiteyProhibited.Queryable()
  524. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  525. .WhereIF(!string.IsNullOrEmpty(dto.Classify), d => d.Classify.Contains(dto.Classify!))
  526. .WhereIF(!string.IsNullOrEmpty(dto.Type), d => d.Type.Contains(dto.Type!))
  527. .OrderByDescending(x => x.CreationTime)
  528. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  529. return new PagedDto<QualityProhibitedDto>(total, _mapper.Map<IReadOnlyList<QualityProhibitedDto>>(items));
  530. }
  531. /// <summary>
  532. /// 获取违禁词实体
  533. /// </summary>
  534. /// <param name="id"></param>
  535. /// <returns></returns>
  536. [HttpGet("prohibited/{id}")]
  537. public async Task<QualityProhibited> ProhibitedEntity(string id)
  538. {
  539. return await _qualiteyProhibited.Queryable()
  540. .FirstAsync(x => x.Id == id);
  541. }
  542. #endregion
  543. /// <summary>
  544. /// 获取质检基本信息
  545. /// </summary>
  546. /// <returns></returns>
  547. [HttpGet("base")]
  548. public async Task<object> Base()
  549. {
  550. var rsp = new
  551. {
  552. QualityState = EnumExts.GetDescriptions<EQualityState>(),
  553. QualitySource = EnumExts.GetDescriptions<EQualitySource>()
  554. };
  555. return rsp;
  556. }
  557. /// <summary>
  558. /// 获取质检项目基本信息
  559. /// </summary>
  560. /// <returns></returns>
  561. [HttpGet("item_base")]
  562. public async Task<object> ItemBase()
  563. {
  564. var rsp = new
  565. {
  566. QualityItemGrouping = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.QualityItemGrouping)
  567. };
  568. return rsp;
  569. }
  570. /// <summary>
  571. /// 获取质检模版基本信息
  572. /// </summary>
  573. /// <returns></returns>
  574. [HttpGet("template_base")]
  575. public async Task<object> TemplateBase()
  576. {
  577. var rsp = new
  578. {
  579. TemplateGrouping = EnumExts.GetDescriptions<ETemplateGrouping>()
  580. };
  581. return rsp;
  582. }
  583. /// <summary>
  584. /// 获取质检违禁词基本信息
  585. /// </summary>
  586. /// <returns></returns>
  587. [HttpGet("prohibited_base")]
  588. public async Task<object> ProhibitedBase()
  589. {
  590. var rsp = new
  591. {
  592. ProhibitedClassify = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ProhibitedClassify),
  593. ProhibitedType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ProhibitedType),
  594. };
  595. return rsp;
  596. }
  597. /// <summary>
  598. /// 智能质检转写_兴唐
  599. /// </summary>
  600. /// <param name="dto"></param>
  601. /// <returns></returns>
  602. [HttpPost("aitransfer_xt")]
  603. [LogFilter("智能质检转写_兴唐")]
  604. public async Task AiTransfer_XT([FromBody] List<AiQualityXTDto> dto)
  605. {
  606. var transfers = new List<QualityTransferRecords>();
  607. foreach (var item in dto)
  608. {
  609. var records = await _qualityTransferRecordsRepository.Queryable().Where(x => x.QualityId == item.Id && x.IsFinished == false).AnyAsync();
  610. if (records)
  611. continue;
  612. var transfer = new QualityTransferRecords();
  613. transfer.QualityId = item.Id;
  614. transfer.IsFinished = false;
  615. transfer.TransferState = EQualityTransferState.NotStarted;
  616. transfers.Add(transfer);
  617. await _qualitey.Updateable().SetColumns(x => new Hotline.Quality.Quality { TransferState = EQualityTransferState.Translating }).Where(x => x.Id == item.Id).ExecuteCommandAsync();
  618. }
  619. await _qualityTransferRecordsRepository.AddRangeAsync(transfers);
  620. }
  621. /// <summary>
  622. /// 智能质检转写_兴唐_定时调用
  623. /// </summary>
  624. /// <param name="dto"></param>
  625. /// <returns></returns>
  626. [AllowAnonymous]
  627. [HttpPost("transfer")]
  628. [LogFilter("智能质检转写_兴唐_定时调用")]
  629. public async Task AiTransfer_XT()
  630. {
  631. var translatings = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.Translating).OrderBy(x => x.TransferTime).ToListAsync();
  632. if (translatings.Any())
  633. {
  634. var transfer = translatings.FirstOrDefault();
  635. if ((DateTime.Now - transfer.TransferTime.Value).TotalMinutes >= 30)
  636. {
  637. await _qualityTransferRecordsRepository.Updateable().SetColumns(x => new QualityTransferRecords { TransferState = EQualityTransferState.Lose }).Where(x => x.Id == transfer.Id).ExecuteCommandAsync();
  638. await _qualitey.Updateable().SetColumns(x => new Hotline.Quality.Quality { TransferState = EQualityTransferState.Lose }).Where(x => x.Id == transfer.QualityId).ExecuteCommandAsync();
  639. }
  640. return;
  641. }
  642. else {
  643. var trany = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.NotStarted).AnyAsync();
  644. if (trany) {
  645. var notStarted = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.NotStarted).OrderBy(x => x.TransferTime).FirstAsync();
  646. await _qualityTransferRecordsRepository.Updateable().SetColumns(x => new QualityTransferRecords { TransferState = EQualityTransferState.Translating, TransferTime = DateTime.Now }).Where(x => x.Id == notStarted.Id).ExecuteCommandAsync();
  647. Task.Run(async () => await _qualityApplication.Transfer_XT(notStarted.QualityId, HttpContext.RequestAborted));
  648. }
  649. }
  650. }
  651. /// <summary>
  652. /// 智能质检结果返回接收
  653. /// </summary>
  654. /// <param name="dto"></param>
  655. /// <returns></returns>
  656. [AllowAnonymous]
  657. [HttpPost("AiResult")]
  658. [LogFilter("智能质检结果返回接收")]
  659. public async Task AiResult([FromBody] List<AiQualityResultDto> dto)
  660. {
  661. //Request.EnableBuffering();
  662. //var sr = new StreamReader(Request.Body);
  663. //var data = await sr.ReadToEndAsync(HttpContext.RequestAborted);
  664. // _logger.LogInformation(data);
  665. // await _logRepository.Updateable().SetColumns( x=> new SystemLog(){ ExecuteParam = data }).Where(x => x.Id == "08dcb132-cf60-4d1f-84ae-eb0c463f2175").ExecuteCommandAsync();
  666. await _qualityApplication.AiResultAsync(dto, HttpContext.RequestAborted);
  667. }
  668. /// <summary>
  669. /// 重推质检
  670. /// </summary>
  671. /// <param name="id"></param>
  672. /// <returns></returns>
  673. [AllowAnonymous]
  674. [HttpPost("AiResultTest/{id}")]
  675. public async Task TaskAsync(string id)
  676. {
  677. var quality = await _qualitey.GetAsync(id, HttpContext.RequestAborted);
  678. var order = await _orderRepository.GetAsync(quality.OrderId, HttpContext.RequestAborted);
  679. if (order != null && !string.IsNullOrEmpty(order.CallId))
  680. {
  681. quality.AiQuality = true;
  682. //var call = await _trCallRecordRepository.GetAsync(x => x.CallAccept == order.CallId, HttpContext.RequestAborted); //由CallAccept改为OtherAccept
  683. //var call = await _trCallRecordRepository.GetAsync(x => x.OtherAccept == order.CallId, HttpContext.RequestAborted);
  684. var audioFile = string.Empty;
  685. var fromNo = string.Empty;
  686. DateTime? callStartTime = null;
  687. if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
  688. {
  689. var call = await _callApplication.GetTianrunCallAsync(order.CallId, HttpContext.RequestAborted);
  690. audioFile = call.RecordingAbsolutePath;
  691. fromNo = call.CPN;
  692. callStartTime = call.CreatedTime;
  693. }
  694. else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
  695. {
  696. var call = await _callApplication.GetCallAsync(order.CallId, HttpContext.RequestAborted);
  697. audioFile = call.AudioFile;
  698. fromNo = call.FromNo;
  699. callStartTime = call.BeginIvrTime;
  700. }
  701. if (_appOptions.Value.IsYiBin)
  702. {
  703. var aiQualityService = _serviceProvider.GetRequiredService<IAiQualityService>();
  704. var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);
  705. try
  706. {
  707. await aiQualityService.CreateAiOrderQualityTask(
  708. quality.Id,
  709. audioFile,
  710. fromNo,
  711. callStartTime,
  712. setting?.SettingValue[0], quality.Source.ToString(), HttpContext.RequestAborted);
  713. }
  714. catch (Exception e)
  715. {
  716. _logger.LogError($"写入智能质检异常3!, \r\n{e.Message}");
  717. }
  718. }
  719. await _qualitey.UpdateAsync(quality, HttpContext.RequestAborted);
  720. }
  721. }
  722. }
  723. }