QualityController.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  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 Hotline.Share.Dtos.File;
  11. using Microsoft.AspNetCore.Mvc;
  12. using XF.Domain.Exceptions;
  13. using Hotline.Share.Dtos.Quality;
  14. using Hotline.Share.Dtos.Order;
  15. using Hotline.Share.Enums.Quality;
  16. using Hotline.Share.Enums.Order;
  17. using XF.Utility.EnumExtensions;
  18. using System.Xml.Linq;
  19. using System.Threading;
  20. using Hotline.CallCenter.Calls;
  21. using Hotline.Application.Quality;
  22. using Microsoft.AspNetCore.Authorization;
  23. using Hotline.Orders;
  24. using Hotline.Ai.Quality;
  25. using Newtonsoft.Json;
  26. using Polly;
  27. using Hotline.Api.Filter;
  28. namespace Hotline.Api.Controllers
  29. {
  30. public class QualityController : BaseController
  31. {
  32. private readonly ISessionContext _sessionContext;
  33. private readonly IMapper _mapper;
  34. private readonly IQualityRepository _qualitey;
  35. private readonly IRepository<QualityDetail> _qualiteyDetail;
  36. private readonly IRepository<QualityItem> _qualiteyItem;
  37. private readonly IRepository<QualityTemplate> _qualityTemplate;
  38. private readonly IRepository<QualityTemplateDetail> _qualiteyTemplateDetail;
  39. private readonly IRepository<QualityProhibited> _qualiteyProhibited;
  40. private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
  41. private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  42. private readonly IQualityApplication _qualityApplication;
  43. private readonly IOrderRepository _orderRepository;
  44. private readonly IAiQualityService _aiQualityService;
  45. private readonly ILogger<QualityController> _logger;
  46. public QualityController(
  47. ISessionContext sessionContext,
  48. IMapper mapper,
  49. IQualityRepository qualitey,
  50. IRepository<Quality.QualityDetail> qualiteyDetail,
  51. IRepository<QualityItem> qualiteyItem,
  52. IRepository<QualityTemplate> qualityTemplate,
  53. IRepository<QualityTemplateDetail> qualiteyTemplateDetail,
  54. IRepository<QualityProhibited> qualiteyProhibited,
  55. ISystemDicDataCacheManager systemDicDataCacheManager,
  56. IRepository<TrCallRecord> trCallRecordRepository,
  57. IQualityApplication qualityApplication,
  58. IOrderRepository orderRepository,
  59. IAiQualityService aiQualityService,
  60. ILogger<QualityController> logger
  61. )
  62. {
  63. _sessionContext = sessionContext;
  64. _mapper = mapper;
  65. _qualitey = qualitey;
  66. _qualiteyDetail = qualiteyDetail;
  67. _qualiteyItem = qualiteyItem;
  68. _qualityTemplate = qualityTemplate;
  69. _qualiteyTemplateDetail = qualiteyTemplateDetail;
  70. _qualiteyProhibited = qualiteyProhibited;
  71. _systemDicDataCacheManager = systemDicDataCacheManager;
  72. _trCallRecordRepository = trCallRecordRepository;
  73. _qualityApplication = qualityApplication;
  74. _orderRepository = orderRepository;
  75. _aiQualityService = aiQualityService;
  76. _logger = logger;
  77. }
  78. #region 质检管理
  79. /// <summary>
  80. /// 删除质检
  81. /// </summary>
  82. /// <param name="dto"></param>
  83. /// <returns></returns>
  84. [HttpDelete]
  85. public async Task Delete([FromBody] DeleteQualityDto dto)
  86. {
  87. foreach (var Id in dto.Ids)
  88. {
  89. await _qualitey.RemoveAsync(x => x.Id == Id);
  90. List<QualityDetail> details = await _qualiteyDetail.Queryable().Where(x => x.QualityId == Id).ToListAsync();
  91. await _qualiteyDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  92. }
  93. }
  94. /// <summary>
  95. /// 更新质检
  96. /// </summary>
  97. /// <param name="dto"></param>
  98. /// <returns></returns>
  99. [Permission(EPermission.UpdateQuality)]
  100. [HttpPut]
  101. public async Task Update([FromBody] UpdateQualityDto dto)
  102. {
  103. await _qualityApplication.UpdateQualityAsync(dto, HttpContext.RequestAborted);
  104. }
  105. /// <summary>
  106. /// 获取质检列表
  107. /// </summary>
  108. /// <param name="dto"></param>
  109. /// <returns></returns>
  110. [HttpGet("list")]
  111. public async Task<PagedDto<QualityDto>> List([FromQuery] QualityListDto dto)
  112. {
  113. var (total, items) = await _qualitey.Queryable()
  114. .Includes(x => x.Order)
  115. .Includes(x => x.Visit)
  116. .Includes(x => x.Visit,e=>e.Employee)
  117. .Includes(x => x.QualityDetails)
  118. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
  119. .WhereIF(dto.State.HasValue, x => x.State == dto.State)
  120. .WhereIF(dto.Source.HasValue, x=> x.Source == dto.Source)
  121. .WhereIF(dto.Source.HasValue && dto.Source == EQualitySource.Accepted, x=> !string.IsNullOrEmpty(x.Order.CallId))
  122. .WhereIF(dto.Source.HasValue && dto.Source == EQualitySource.Visit, x => !string.IsNullOrEmpty(x.Visit.CallId))
  123. .WhereIF(dto.CreationTimeStart.HasValue, x => x.CreationTime >= dto.CreationTimeStart)
  124. .WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
  125. .WhereIF(dto.MaxGrade.HasValue,x=>x.Grade <= dto.MaxGrade)
  126. .WhereIF(dto.MinGrade.HasValue,x => x.Grade >= dto.MinGrade)
  127. .OrderByDescending(x => x.CreationTime)
  128. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  129. return new PagedDto<QualityDto>(total, _mapper.Map<IReadOnlyList<QualityDto>>(items));
  130. }
  131. /// <summary>
  132. /// 获取质检实体
  133. /// </summary>
  134. /// <param name="id"></param>
  135. /// <returns></returns>
  136. [HttpGet("{id}")]
  137. public async Task<QualityDto> Entity(string id)
  138. {
  139. var quality = await _qualitey.Queryable()
  140. .Includes(x => x.Order)
  141. .Includes(x => x.Visit)
  142. .Includes(x => x.Visit, e => e.Employee)
  143. .Includes(x => x.QualityDetails)
  144. .FirstAsync(x => x.Id == id);
  145. var qualityDto = _mapper.Map<QualityDto>(quality);
  146. if (qualityDto.Order != null) {
  147. var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Order.CallId).FirstAsync();
  148. if (call != null)
  149. {
  150. qualityDto.Order.RecordingBaseAddress = call.RecordingBaseAddress;
  151. qualityDto.Order.RecordingAbsolutePath = call.RecordingAbsolutePath;
  152. }
  153. }
  154. if (qualityDto.Visit != null)
  155. {
  156. var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == qualityDto.Visit.CallId).FirstAsync();
  157. if (call != null)
  158. {
  159. qualityDto.Visit.RecordingBaseAddress = call.RecordingBaseAddress;
  160. qualityDto.Visit.RecordingAbsolutePath = call.RecordingAbsolutePath;
  161. }
  162. }
  163. return qualityDto;
  164. }
  165. #endregion
  166. #region 质检项管理
  167. /// <summary>
  168. /// 新增项目
  169. /// </summary>
  170. /// <param name="dtos"></param>
  171. /// <returns></returns>
  172. [Permission(EPermission.AddQualityItem)]
  173. [HttpPost("item")]
  174. public async Task Add([FromBody] QualityItemAddDto dto)
  175. {
  176. var count = await _qualiteyItem.CountAsync(x => x.Name == dto.Name);
  177. if (count > 0)
  178. throw UserFriendlyException.SameMessage("质检项目名称已存在");
  179. var model = _mapper.Map<QualityItem>(dto);
  180. await _qualiteyItem.AddAsync(model, HttpContext.RequestAborted);
  181. }
  182. ///// <summary>
  183. ///// 删除项目
  184. ///// </summary>
  185. ///// <param name="dto"></param>
  186. ///// <returns></returns>
  187. //[Permission(EPermission.DeleteQualityItem)]
  188. //[HttpDelete("item")]
  189. //public async Task Delete([FromBody] QualityItemDeleteDto dto)
  190. //{
  191. // await _qualiteyItem.RemoveAsync(x => x.Id == dto.Id);
  192. //}
  193. /// <summary>
  194. /// 删除项目
  195. /// </summary>
  196. /// <param name="dto"></param>
  197. /// <returns></returns>
  198. [Permission(EPermission.DeleteQualityItem)]
  199. [HttpDelete("itemBatch")]
  200. public async Task Delete([FromBody] QualityItemBatchDeleteDto dto)
  201. {
  202. List<QualityItem> items = await _qualiteyItem.Queryable().In(x => x.Id, dto.Ids).ToListAsync();
  203. foreach (var item in items)
  204. {
  205. var detail = await _qualiteyDetail.Queryable().Where(x => x.Name == item.Name).AnyAsync();
  206. //质检中已存在不可以删
  207. if (detail) items.Remove(item);
  208. }
  209. if (items.Any())
  210. {
  211. await _qualiteyItem.RemoveRangeAsync(items, true, HttpContext.RequestAborted);
  212. var tempItems = await _qualiteyTemplateDetail.Queryable().In(x => x.ItemId, items.Select(x => x.Id)).ToListAsync(HttpContext.RequestAborted);
  213. if (tempItems.Any()) await _qualiteyTemplateDetail.RemoveRangeAsync(tempItems, HttpContext.RequestAborted);
  214. }
  215. }
  216. /// <summary>
  217. /// 更新项目
  218. /// </summary>
  219. /// <param name="dto"></param>
  220. /// <returns></returns>
  221. [Permission(EPermission.UpdateQualityItem)]
  222. [HttpPut("item")]
  223. public async Task Update([FromBody] QualityItemUpdateDto dto)
  224. {
  225. var item = await _qualiteyItem.GetAsync(dto.Id, HttpContext.RequestAborted);
  226. if (item is null)
  227. throw UserFriendlyException.SameMessage("无效质检项目");
  228. if (item.IsEnable != dto.IsEnable || item.Name != dto.Name) {
  229. var detail = await _qualiteyDetail.Queryable().Where(x => x.Name == item.Name && !x.IsDeleted).AnyAsync();
  230. if(detail) throw UserFriendlyException.SameMessage("质检项目在中心质检中已使用,不能修改状态和名称!");
  231. }
  232. _mapper.Map(dto, item);
  233. item.LastModificationName = _sessionContext.UserName;
  234. await _qualiteyItem.UpdateAsync(item, HttpContext.RequestAborted);
  235. }
  236. /// <summary>
  237. /// 获取项目列表
  238. /// </summary>
  239. /// <param name="dto"></param>
  240. /// <returns></returns>
  241. [Permission(EPermission.QualityItemList)]
  242. [HttpGet("item/list")]
  243. public async Task<PagedDto<QualityItemDto>> List([FromQuery] QualityItemListDto dto)
  244. {
  245. var (total, items) = await _qualiteyItem.Queryable()
  246. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  247. .WhereIF(!string.IsNullOrEmpty(dto.GroupingName), d => d.GroupingName.Contains(dto.GroupingName!))
  248. .WhereIF(dto.IsEnable.HasValue,d=>d.IsEnable == dto.IsEnable)
  249. .OrderByDescending(x => x.CreationTime)
  250. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  251. return new PagedDto<QualityItemDto>(total, _mapper.Map<IReadOnlyList<QualityItemDto>>(items));
  252. }
  253. /// <summary>
  254. /// 获取项目实体
  255. /// </summary>
  256. /// <param name="id"></param>
  257. /// <returns></returns>
  258. [HttpGet("item/{id}")]
  259. public async Task<QualityItem> ItemEntity(string id)
  260. {
  261. return await _qualiteyItem.Queryable()
  262. .FirstAsync(x => x.Id == id);
  263. }
  264. #endregion
  265. #region 质检模版管理
  266. /// <summary>
  267. /// 新增模版
  268. /// </summary>
  269. /// <param name="dtos"></param>
  270. /// <returns></returns>
  271. [Permission(EPermission.AddQualityTemplate)]
  272. [HttpPost("template")]
  273. public async Task Add([FromBody] TemplateAddDto dto)
  274. {
  275. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.IsEnable == 1);
  276. if (groupingCount > 0 && dto.IsEnable == 1)
  277. throw UserFriendlyException.SameMessage("当前已存在");
  278. var names = dto.TemplateDetails.Select(x => x.ItemId).ToList();
  279. var nameCount= names.GroupBy(x => x).Count(c => c.Count() > 1);
  280. if (nameCount > 0)
  281. throw UserFriendlyException.SameMessage("质检模版存在重复质检项");
  282. var model = _mapper.Map<QualityTemplate>(dto);
  283. var id = await _qualityTemplate.AddAsync(model, HttpContext.RequestAborted);
  284. if (!string.IsNullOrEmpty(id))
  285. {
  286. foreach (var item in dto.TemplateDetails)
  287. {
  288. item.TemplateId = id;
  289. }
  290. List<QualityTemplateDetail> details = _mapper.Map<List<QualityTemplateDetail>>(dto.TemplateDetails);
  291. await _qualiteyTemplateDetail.AddRangeAsync(details, HttpContext.RequestAborted);
  292. }
  293. }
  294. /// <summary>
  295. /// 删除模版
  296. /// </summary>
  297. /// <param name="dto"></param>
  298. /// <returns></returns>
  299. [Permission(EPermission.DeleteQualityTemplate)]
  300. [HttpDelete("template")]
  301. public async Task Delete([FromBody] TemplateDeleteDto dto)
  302. {
  303. await _qualityTemplate.RemoveAsync(x => x.Id == dto.Id);
  304. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().Where(x => x.TemplateId == dto.Id).ToListAsync();
  305. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  306. }
  307. /// <summary>
  308. /// 删除模版
  309. /// </summary>
  310. /// <param name="dto"></param>
  311. /// <returns></returns>
  312. [Permission(EPermission.DeleteQualityTemplate)]
  313. [HttpDelete("templateBatch")]
  314. public async Task Delete([FromBody] TemplateBatchDeleteDto dto)
  315. {
  316. List<QualityTemplate> templates = await _qualityTemplate.Queryable().In(x=>x.Id,dto.Ids).ToListAsync();
  317. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().In(x => x.TemplateId,dto.Ids).ToListAsync();
  318. await _qualityTemplate.RemoveRangeAsync(templates, HttpContext.RequestAborted);
  319. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  320. }
  321. /// <summary>
  322. /// 更新模版
  323. /// </summary>
  324. /// <param name="dto"></param>
  325. /// <returns></returns>
  326. [Permission(EPermission.UpdateQualityTemplate)]
  327. [HttpPut("template")]
  328. public async Task Update([FromBody] TemplateUpdateDto dto)
  329. {
  330. var template = await _qualityTemplate.GetAsync(dto.Id, HttpContext.RequestAborted);
  331. if (template is null)
  332. throw UserFriendlyException.SameMessage("无效质检模版");
  333. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.Id != dto.Id && x.IsEnable == 1);
  334. if (groupingCount > 0)
  335. throw UserFriendlyException.SameMessage("当前质检分类已存在");
  336. _mapper.Map(dto, template);
  337. template.LastModificationName = _sessionContext.UserName;
  338. await _qualityTemplate.UpdateAsync(template, HttpContext.RequestAborted);
  339. if (dto.TemplateDetails.Any())
  340. {
  341. List<QualityTemplateDetail> details = await _qualiteyTemplateDetail.Queryable().Where(x => x.TemplateId == dto.Id).ToListAsync();
  342. await _qualiteyTemplateDetail.RemoveRangeAsync(details, HttpContext.RequestAborted);
  343. foreach (var item in dto.TemplateDetails)
  344. {
  345. item.TemplateId = dto.Id;
  346. }
  347. List<QualityTemplateDetail> newDetails = _mapper.Map<List<QualityTemplateDetail>>(dto.TemplateDetails);
  348. await _qualiteyTemplateDetail.AddRangeAsync(newDetails, HttpContext.RequestAborted);
  349. }
  350. }
  351. /// <summary>
  352. /// 获取模版列表
  353. /// </summary>
  354. /// <param name="dto"></param>
  355. /// <returns></returns>
  356. [Permission(EPermission.QualityTemplateList)]
  357. [HttpGet("template/list")]
  358. public async Task<PagedDto<QualityTemplateDto>> List([FromQuery] TemplateListDto dto)
  359. {
  360. var (total, items) = await _qualityTemplate.Queryable()
  361. .Includes(x => x.templateDetails)
  362. .Includes(x=>x.templateDetails,y=>y.QualityItem)
  363. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  364. .WhereIF(dto.Grouping.HasValue, d => d.Grouping == dto.Grouping)
  365. .WhereIF(dto.IsEnable.HasValue, d => d.IsEnable == dto.IsEnable)
  366. .OrderByDescending(x => x.CreationTime)
  367. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  368. return new PagedDto<QualityTemplateDto>(total, _mapper.Map<IReadOnlyList<QualityTemplateDto>>(items));
  369. }
  370. /// <summary>
  371. /// 获取模版实体
  372. /// </summary>
  373. /// <param name="id"></param>
  374. /// <returns></returns>
  375. [HttpGet("template/{id}")]
  376. public async Task<QualityTemplateDto> TemplateEntity(string id)
  377. {
  378. var template = await _qualityTemplate.Queryable()
  379. .Includes(x => x.templateDetails)
  380. .Includes(x => x.templateDetails, y => y.QualityItem)
  381. .FirstAsync(x => x.Id == id);
  382. return _mapper.Map<QualityTemplateDto>(template);
  383. }
  384. /// <summary>
  385. /// 启禁用
  386. /// </summary>
  387. /// <param name="dto"></param>
  388. /// <returns></returns>
  389. [Permission(EPermission.EnableQualityTemplate)]
  390. [HttpPut("template/enable")]
  391. public async Task Enable([FromBody] TemplateUpdateDto dto)
  392. {
  393. var template = await _qualityTemplate.GetAsync(dto.Id, HttpContext.RequestAborted);
  394. var groupingCount = await _qualityTemplate.CountAsync(x => x.Grouping == dto.Grouping && x.Id != dto.Id && x.IsEnable == 1);
  395. if (groupingCount > 0)
  396. throw UserFriendlyException.SameMessage("当前质检分类已存在");
  397. if (template is null)
  398. throw UserFriendlyException.SameMessage("无效质检模版");
  399. _mapper.Map(dto, template);
  400. await _qualityTemplate.UpdateAsync(template, HttpContext.RequestAborted);
  401. }
  402. #endregion
  403. #region 质检词库管理
  404. /// <summary>
  405. /// 新增违禁词
  406. /// </summary>
  407. /// <param name="dtos"></param>
  408. /// <returns></returns>
  409. [Permission(EPermission.AddQualityProhibited)]
  410. [HttpPost("prohibited")]
  411. public async Task Add([FromBody] ProhibitedAddDto dto)
  412. {
  413. var model = _mapper.Map<QualityProhibited>(dto);
  414. await _qualiteyProhibited.AddAsync(model, HttpContext.RequestAborted);
  415. }
  416. /// <summary>
  417. /// 删除违禁词
  418. /// </summary>
  419. /// <param name="dto"></param>
  420. /// <returns></returns>
  421. [Permission(EPermission.DeleteQualityProhibited)]
  422. [HttpDelete("prohibited")]
  423. public async Task Delete([FromBody] ProhibitedDeleteDto dto)
  424. {
  425. await _qualiteyProhibited.RemoveAsync(x => x.Id == dto.Id);
  426. }
  427. /// <summary>
  428. /// 删除违禁词
  429. /// </summary>
  430. /// <param name="dto"></param>
  431. /// <returns></returns>
  432. [Permission(EPermission.DeleteQualityProhibited)]
  433. [HttpDelete("prohibitedBatch")]
  434. public async Task Delete([FromBody] ProhibitedBatchDeleteDto dto)
  435. {
  436. List<QualityProhibited> prohibiteds = await _qualiteyProhibited.Queryable().In(x=>x.Id,dto.Ids).ToListAsync();
  437. await _qualiteyProhibited.RemoveRangeAsync(prohibiteds, HttpContext.RequestAborted);
  438. }
  439. /// <summary>
  440. /// 更新违禁词
  441. /// </summary>
  442. /// <param name="dto"></param>
  443. /// <returns></returns>
  444. [Permission(EPermission.UpdateQualityProhibited)]
  445. [HttpPut("prohibited")]
  446. public async Task Update([FromBody] ProhibitedUpdateDto dto)
  447. {
  448. var prohibited = await _qualiteyProhibited.GetAsync(dto.Id, HttpContext.RequestAborted);
  449. if (prohibited is null)
  450. throw UserFriendlyException.SameMessage("无效质检模版");
  451. _mapper.Map(dto, prohibited);
  452. prohibited.LastModificationName = _sessionContext.UserName;
  453. await _qualiteyProhibited.UpdateAsync(prohibited, HttpContext.RequestAborted);
  454. }
  455. /// <summary>
  456. /// 获取违禁词列表
  457. /// </summary>
  458. /// <param name="dto"></param>
  459. /// <returns></returns>
  460. [Permission(EPermission.QualityProhibitedList)]
  461. [HttpGet("prohibited/list")]
  462. public async Task<PagedDto<QualityProhibitedDto>> List([FromQuery] ProhibitedListDto dto)
  463. {
  464. var (total, items) = await _qualiteyProhibited.Queryable()
  465. .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
  466. .WhereIF(!string.IsNullOrEmpty(dto.Classify), d => d.Classify.Contains(dto.Classify!))
  467. .WhereIF(!string.IsNullOrEmpty(dto.Type), d => d.Type.Contains(dto.Type!))
  468. .OrderByDescending(x => x.CreationTime)
  469. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  470. return new PagedDto<QualityProhibitedDto>(total, _mapper.Map<IReadOnlyList<QualityProhibitedDto>>(items));
  471. }
  472. /// <summary>
  473. /// 获取违禁词实体
  474. /// </summary>
  475. /// <param name="id"></param>
  476. /// <returns></returns>
  477. [HttpGet("prohibited/{id}")]
  478. public async Task<QualityProhibited> ProhibitedEntity(string id)
  479. {
  480. return await _qualiteyProhibited.Queryable()
  481. .FirstAsync(x => x.Id == id);
  482. }
  483. #endregion
  484. /// <summary>
  485. /// 获取质检基本信息
  486. /// </summary>
  487. /// <returns></returns>
  488. [HttpGet("base")]
  489. public async Task<object> Base()
  490. {
  491. var rsp = new
  492. {
  493. QualityState = EnumExts.GetDescriptions<EQualityState>(),
  494. QualitySource = EnumExts.GetDescriptions<EQualitySource>()
  495. };
  496. return rsp;
  497. }
  498. /// <summary>
  499. /// 获取质检项目基本信息
  500. /// </summary>
  501. /// <returns></returns>
  502. [HttpGet("item_base")]
  503. public async Task<object> ItemBase()
  504. {
  505. var rsp = new
  506. {
  507. QualityItemGrouping = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.QualityItemGrouping)
  508. };
  509. return rsp;
  510. }
  511. /// <summary>
  512. /// 获取质检模版基本信息
  513. /// </summary>
  514. /// <returns></returns>
  515. [HttpGet("template_base")]
  516. public async Task<object> TemplateBase()
  517. {
  518. var rsp = new
  519. {
  520. TemplateGrouping = EnumExts.GetDescriptions<ETemplateGrouping>()
  521. };
  522. return rsp;
  523. }
  524. /// <summary>
  525. /// 获取质检违禁词基本信息
  526. /// </summary>
  527. /// <returns></returns>
  528. [HttpGet("prohibited_base")]
  529. public async Task<object> ProhibitedBase()
  530. {
  531. var rsp = new
  532. {
  533. ProhibitedClassify = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ProhibitedClassify),
  534. ProhibitedType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ProhibitedType),
  535. };
  536. return rsp;
  537. }
  538. /// <summary>
  539. /// 智能质检结果返回接收
  540. /// </summary>
  541. /// <param name="dto"></param>
  542. /// <returns></returns>
  543. [AllowAnonymous]
  544. [HttpPost("AiResult")]
  545. [LogFilter("智能质检结果返回接收")]
  546. public async Task AiResult([FromBody] List<AiQualityResultDto> dto)
  547. {
  548. //Request.EnableBuffering();
  549. //var sr = new StreamReader(Request.Body);
  550. //var data = await sr.ReadToEndAsync(HttpContext.RequestAborted);
  551. //_logger.LogInformation(data);
  552. foreach (var item in dto)
  553. {
  554. var quality = await _qualitey.GetAsync(item.record_id);
  555. if (quality is { State: EQualityState.Apply } && item.score_items != null && item.score_items.Any())
  556. {
  557. List<QualityDetail> details = new List<QualityDetail>();
  558. foreach (var item2 in item.score_items)
  559. {
  560. if (item2.score > 0)
  561. {
  562. var detailsSentence = new List<QualityDetail>();
  563. QualityDetail detail = new QualityDetail
  564. {
  565. QualityId = quality.Id,
  566. Second = 0,
  567. EndSecond = 0,
  568. Name = item2.name,
  569. Content = item2.description,
  570. Intelligent = true,
  571. Grade = item2.score,
  572. Check = true,
  573. };
  574. if (item2?.qualityModels?.Count > 0)
  575. {
  576. foreach (var models in item2.qualityModels)
  577. {
  578. if (models?.sentenceResults?.Count > 0)
  579. {
  580. for (int i = 0; i < models.sentenceResults.Count; i++)
  581. {
  582. var newDetail = new QualityDetail();
  583. _mapper.Map(detail,newDetail);
  584. var sentenceList = item.trans_data.sentence_list.First(x => x.index == models.sentenceResults[i].index);
  585. newDetail.Second = sentenceList.start;
  586. newDetail.EndSecond = sentenceList.end == null? 0: sentenceList.end;
  587. newDetail.Content = sentenceList.text;
  588. detailsSentence.Add(newDetail);
  589. }
  590. }
  591. }
  592. }
  593. if (item2?.audioAttributes?.Count > 0)
  594. {
  595. foreach (var audio in item2.audioAttributes)
  596. {
  597. if (audio?.sentenceResults?.Count > 0)
  598. {
  599. for (int i = 0; i < audio.sentenceResults.Count; i++)
  600. {
  601. var newDetail = new QualityDetail() ;
  602. _mapper.Map(detail,newDetail);
  603. var sentenceList = item.trans_data.sentence_list.First(x => x.index == audio.sentenceResults[i].index);
  604. newDetail.Second = sentenceList.start;
  605. newDetail.EndSecond = sentenceList.end == null ? 0 : sentenceList.end;
  606. newDetail.Content = sentenceList.text;
  607. detailsSentence.Add(newDetail);
  608. }
  609. }
  610. }
  611. }
  612. if (detailsSentence.Count == 0)
  613. {
  614. details.Add(detail);
  615. }
  616. else {
  617. details.AddRange(detailsSentence);
  618. }
  619. }
  620. }
  621. await _qualiteyDetail.AddRangeAsync(details);
  622. }
  623. }
  624. }
  625. /// <summary>
  626. /// 重推质检
  627. /// </summary>
  628. /// <param name="id"></param>
  629. /// <returns></returns>
  630. [AllowAnonymous]
  631. [HttpPost("AiResultTest/{id}")]
  632. public async Task TaskAsync(string id)
  633. {
  634. var quality = await _qualitey.GetAsync(id, HttpContext.RequestAborted);
  635. var order = await _orderRepository.GetAsync(quality.OrderId, HttpContext.RequestAborted);
  636. if (order != null && !string.IsNullOrEmpty(order.CallId))
  637. {
  638. quality.AiQuality = true;
  639. var call = await _trCallRecordRepository.GetAsync(x => x.CallAccept == order.CallId, HttpContext.RequestAborted);
  640. await _aiQualityService.CreateAiOrderQualityTask(quality, call, order, HttpContext.RequestAborted);
  641. await _qualitey.UpdateAsync(quality, HttpContext.RequestAborted);
  642. }
  643. }
  644. }
  645. }