KnowApplication.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. using Hotline.Application.Tools;
  2. using Hotline.Configurations;
  3. using Hotline.KnowledgeBase;
  4. using Hotline.Pdf;
  5. using Hotline.Repository.SqlSugar.Extensions;
  6. using Hotline.Settings.Hotspots;
  7. using Hotline.Share.Dtos;
  8. using Hotline.Share.Dtos.Knowledge;
  9. using Hotline.Share.Enums.KnowledgeBase;
  10. using Hotline.Share.Requests;
  11. using Hotline.Share.Tools;
  12. using Mapster;
  13. using MapsterMapper;
  14. using Microsoft.Extensions.Options;
  15. using PanGu;
  16. using SqlSugar;
  17. using XF.Domain.Authentications;
  18. using XF.Domain.Dependency;
  19. using XF.Domain.Exceptions;
  20. using XF.Domain.Repository;
  21. namespace Hotline.Application.Knowledge
  22. {
  23. public class KnowApplication : IKnowApplication, IScopeDependency
  24. {
  25. private readonly IKnowledgeRepository _knowledgeRepository;
  26. private readonly IRepository<KnowledgePv> _knowledgePvepository;
  27. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  28. private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
  29. private readonly IRepository<KnowledgeApply> _knowledgeApplyRepository;
  30. private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
  31. private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
  32. private readonly IPdfManager _pdfManager;
  33. private readonly ISessionContext _sessionContext;
  34. private readonly IMapper _mapper;
  35. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  36. /// <summary>
  37. ///
  38. /// </summary>
  39. /// <param name="knowledgeRepository"></param>
  40. /// <param name="knowledgeApplyRepository"></param>
  41. /// <param name="sessionContext"></param>
  42. /// <param name="knowledgeDomainService"></param>
  43. /// <param name="mapper"></param>
  44. public KnowApplication(IKnowledgeRepository knowledgeRepository, IOptionsSnapshot<AppConfiguration> appOptions,
  45. IRepository<KnowledgeApply> knowledgeApplyRepository, ISessionContext sessionContext, IMapper mapper,
  46. IRepository<KnowledgeType> knowledgeTypeRepository, IRepository<Hotspot> hotspotTypeRepository,
  47. IRepository<KnowledgeWord> knowledgeWordRepository, IRepository<KnowledgePv> knowledgePvepository,
  48. IRepository<KnowledgeHotWord> knowledgeHotWordRepository, IPdfManager pdfManager)
  49. {
  50. _knowledgeRepository = knowledgeRepository;
  51. _knowledgeApplyRepository = knowledgeApplyRepository;
  52. _sessionContext = sessionContext;
  53. _mapper = mapper;
  54. _knowledgeTypeRepository = knowledgeTypeRepository;
  55. _hotspotTypeRepository = hotspotTypeRepository;
  56. _knowledgeWordRepository = knowledgeWordRepository;
  57. _knowledgePvepository = knowledgePvepository;
  58. _knowledgeHotWordRepository = knowledgeHotWordRepository;
  59. _pdfManager = pdfManager;
  60. _appOptions = appOptions;
  61. }
  62. /// <summary>
  63. /// 知识库查询
  64. /// </summary>
  65. /// <param name="pagedDto"></param>
  66. /// <returns></returns>
  67. public async Task<(int, IList<KnowledgeDataDto>)> GetKnowList(KnowPagedListDto pagedDto, CancellationToken cancellationToken)
  68. {
  69. if (!_sessionContext.OrgIsCenter)
  70. {
  71. pagedDto.Attribution = "部门知识库";
  72. }
  73. if (_appOptions.Value.IsZiGong || _appOptions.Value.IsLuZhou)
  74. {
  75. pagedDto.Attribution = string.Empty;
  76. }
  77. var typeSpliceName = string.Empty;
  78. var hotspotHotSpotFullName = string.Empty;
  79. if (!string.IsNullOrEmpty(pagedDto.KnowledgeTypeId))
  80. {
  81. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == pagedDto.KnowledgeTypeId);
  82. typeSpliceName = type?.SpliceName;
  83. }
  84. if (!string.IsNullOrEmpty(pagedDto.HotspotId))
  85. {
  86. var hotspot = await _hotspotTypeRepository.GetAsync(x => x.Id == pagedDto.HotspotId);
  87. hotspotHotSpotFullName = hotspot?.HotSpotFullName;
  88. }
  89. var query = _knowledgeRepository.Queryable();
  90. switch (pagedDto.Status)
  91. {
  92. case EKnowledgeStatusRequest.OnShelf:
  93. query.Where(d => d.Status == EKnowledgeStatus.OnShelf
  94. && (d.ExpiredTime == null || (d.ExpiredTime != null && d.ExpiredTime > DateTime.Now)));
  95. break;
  96. case EKnowledgeStatusRequest.OffShelf:
  97. query.Where(d => d.Status == EKnowledgeStatus.OffShelf
  98. || (d.ExpiredTime != null && d.ExpiredTime <= DateTime.Now && d.Status != EKnowledgeStatus.Drafts));
  99. break;
  100. case EKnowledgeStatusRequest.Auditing:
  101. query.Where(d => d.Status == EKnowledgeStatus.Auditing);
  102. switch (pagedDto.ModuleCode)
  103. {
  104. case "add":
  105. query.Where(d => d.KnowledgeApproves.Any(x => x.KnowledgeApproveType == EKnowledgeApproveType.Add
  106. && x.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle));
  107. break;
  108. case "update":
  109. query.Where(d => d.KnowledgeApproves.Any(x => x.KnowledgeApproveType == EKnowledgeApproveType.Update
  110. && x.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle));
  111. break;
  112. case "delete":
  113. query.Where(d => d.KnowledgeApproves.Any(x => x.KnowledgeApproveType == EKnowledgeApproveType.Delete
  114. && x.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle));
  115. break;
  116. case "offshelf":
  117. query.Where(d => d.KnowledgeApproves.Any(x => x.KnowledgeApproveType == EKnowledgeApproveType.OffShelf
  118. && x.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle));
  119. break;
  120. }
  121. break;
  122. case EKnowledgeStatusRequest.Drafts:
  123. switch (pagedDto.NewDraftsStatus)
  124. {
  125. case EKnowledgeDraftTypeRequest.All:
  126. query.Where(d => (d.Status == EKnowledgeStatus.Drafts && d.CreatorId == _sessionContext.UserId)
  127. || d.Status == EKnowledgeStatus.Revert);
  128. break;
  129. case EKnowledgeDraftTypeRequest.UnApproval:
  130. query.Where(d => (d.Status == EKnowledgeStatus.Drafts && d.CreatorId == _sessionContext.UserId));
  131. break;
  132. case EKnowledgeDraftTypeRequest.Failed:
  133. query.Where(d => d.Status == EKnowledgeStatus.Revert);
  134. break;
  135. default:
  136. throw new ArgumentOutOfRangeException();
  137. }
  138. break;
  139. case EKnowledgeStatusRequest.All:
  140. break;
  141. default:
  142. throw new ArgumentOutOfRangeException();
  143. }
  144. if (!_sessionContext.OrgIsCenter)
  145. query.Where(x => x.KnowledgeTypes.Any(t => t.Orgs.Any(to => to.Id == _sessionContext.RequiredOrgId)));
  146. var (total, temp) = await query
  147. //.Includes(x => x.User)
  148. .Includes(x => x.SystemOrganize)
  149. .Includes(x => x.SourceOrganize)
  150. .Includes(x => x.KnowledgeTypes)
  151. .Includes(x => x.HotspotType)
  152. //.Includes(x => x.Workflow)
  153. //.Includes(x => x.KnowledgeType)
  154. //.Where(x => x.IsDeleted == false)
  155. //.Where(x => x.KnowledgeType.Any(t => t.KnowledgeType.KnowledgeTypeOrgs.Any(to => to.OrgId == _sessionContext.RequiredOrgId)
  156. // || t.KnowledgeType.KnowledgeTypeOrgs.Any() == false))
  157. //.Where(x => x.KnowledgeType.Any(t => t.KnowledgeType.Orgs.Any(to => to.Id == _sessionContext.RequiredOrgId)
  158. // || t.KnowledgeType.Orgs.Any() == false))
  159. //.Where(x => x.KnowledgeTypes.Any(t => t.KnowledgeTypeOrgs.Any(to => to.OrgId == _sessionContext.RequiredOrgId)
  160. // || t.KnowledgeTypeOrgs.Any() == false))
  161. //.Where(x => x.KnowledgeTypes.Any(t => t.Orgs.Any(to => to.Id == _sessionContext.RequiredOrgId)
  162. // /*|| t.Orgs.Any() == false*/))
  163. //.Where(x => (x.Status == EKnowledgeStatus.Drafts && x.CreatorId == _sessionContext.UserId) || (x.Status != EKnowledgeStatus.Drafts))
  164. .WhereIF(!string.IsNullOrEmpty(pagedDto.Title), x => x.Title.Contains(pagedDto.Title!))
  165. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), x => x.Title.Contains(pagedDto.Keyword!) || x.CreatorName.Contains(pagedDto.Keyword!) || x.CreatorOrgName.Contains(pagedDto.Keyword!) || x.SourceOrganize.Name.Contains(pagedDto.Keyword!))
  166. //.WhereIF(pagedDto.Status.HasValue && pagedDto.Status != EKnowledgeStatus.OffShelf && pagedDto.Status != EKnowledgeStatus.NewDrafts && pagedDto.Status != EKnowledgeStatus.All,
  167. // x => x.Status == pagedDto.Status && ((x.ExpiredTime != null && x.ExpiredTime > DateTime.Now) || x.ExpiredTime == null))
  168. //.WhereIF(pagedDto.Status.HasValue && pagedDto.Status == EKnowledgeStatus.OffShelf,
  169. // x => x.Status == pagedDto.Status || (x.ExpiredTime != null && x.ExpiredTime < DateTime.Now && x.Status != EKnowledgeStatus.Drafts))
  170. .WhereIF(pagedDto.IsPublic.HasValue, x => x.IsPublic == pagedDto.IsPublic)
  171. .WhereIF(!string.IsNullOrEmpty(pagedDto.Summary), x => x.Summary != null && x.Summary.Contains(pagedDto.Summary!))
  172. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.StartsWith(typeSpliceName)))
  173. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeTypes.Any(t => t.SpliceName.StartsWith(typeSpliceName)))
  174. .WhereIF(!string.IsNullOrEmpty(hotspotHotSpotFullName), x => x.HotspotType.HotSpotFullName.EndsWith(hotspotHotSpotFullName!))
  175. .WhereIF(!string.IsNullOrEmpty(pagedDto.CreateOrgId), x => x.CreatorOrgId != null && x.CreatorOrgId.StartsWith(pagedDto.CreateOrgId!))
  176. //.WhereIF(!string.IsNullOrEmpty(pagedDto.ModuleCode), x => x.Workflow.ModuleCode == pagedDto.ModuleCode)
  177. //.WhereIF(pagedDto.Status == EKnowledgeStatus.NewDrafts, x => x.Status == EKnowledgeStatus.Drafts || x.Status == EKnowledgeStatus.Revert)
  178. //.WhereIF(pagedDto.NewDraftsStatus is EKnowledgeStatus.Drafts, x => x.Status == EKnowledgeStatus.Drafts)
  179. //.WhereIF(pagedDto.NewDraftsStatus is EKnowledgeStatus.Revert, x => x.Status == EKnowledgeStatus.Revert)
  180. .WhereIF(pagedDto.CreationStartTime.HasValue, x => x.CreationTime >= pagedDto.CreationStartTime)
  181. .WhereIF(pagedDto.CreationEndTime.HasValue, x => x.CreationTime <= pagedDto.CreationEndTime)
  182. .WhereIF(pagedDto.StartOnShelfTime.HasValue, x => x.OnShelfTime >= pagedDto.StartOnShelfTime)
  183. .WhereIF(pagedDto.EndOnShelfTime.HasValue, x => x.OnShelfTime <= pagedDto.EndOnShelfTime)
  184. .WhereIF(pagedDto.StartOffShelfTime.HasValue, x => x.OffShelfTime >= pagedDto.StartOffShelfTime)
  185. .WhereIF(pagedDto.EndOffShelfTime.HasValue, x => x.OffShelfTime <= pagedDto.EndOffShelfTime)
  186. .WhereIF(pagedDto.StartUpdateTime.HasValue, x => x.LastModificationTime >= pagedDto.StartUpdateTime)
  187. .WhereIF(pagedDto.EndUpdateTime.HasValue, x => x.LastModificationTime <= pagedDto.EndUpdateTime)
  188. .WhereIF(!string.IsNullOrEmpty(pagedDto.Attribution), x => x.Attribution == pagedDto.Attribution)
  189. .WhereIF(!string.IsNullOrEmpty(pagedDto.CreatorName), x => x.CreatorName.Contains(pagedDto.CreatorName))
  190. .OrderByDescending(d => d.CreationTime)
  191. .ToPagedListAsync(pagedDto, cancellationToken);
  192. //返回数据
  193. return (total, _mapper.Map<IList<KnowledgeDataDto>>(temp));
  194. }
  195. /// <summary>
  196. /// 知识申请查询
  197. /// </summary>
  198. /// <param name="pagedDto"></param>
  199. /// <param name="cancellationToken"></param>
  200. /// <returns></returns>
  201. public async Task<PagedDto<KnowledgeApplyHandlePageDto>> GetApplyList(KnowledgeApplyPagedDto pagedDto, CancellationToken cancellationToken)
  202. {
  203. var (total, items) = await _knowledgeApplyRepository
  204. .Queryable()
  205. .Includes(it => it.User)
  206. .Includes(it => it.SystemOrganize)
  207. .Where(d => d.CreatorId == _sessionContext.RequiredUserId)
  208. .WhereIF(pagedDto.Status.HasValue, d => d.Status == pagedDto.Status)
  209. .WhereIF(pagedDto.ApplyType.HasValue, d => d.KnowledgeApplyType == pagedDto.ApplyType)
  210. .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "0", d => d.IsOvertime == true)
  211. .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "1", d => d.IsOvertime == false)
  212. .WhereIF(pagedDto.StartTime.HasValue, d => d.CreationTime >= pagedDto.StartTime)
  213. .WhereIF(pagedDto.EndTime.HasValue, d => d.CreationTime <= pagedDto.EndTime)
  214. .OrderByDescending(p => p.CreationTime)
  215. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, cancellationToken);
  216. return new PagedDto<KnowledgeApplyHandlePageDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApplyHandlePageDto>>(items));
  217. }
  218. /// <summary>
  219. /// 申请处理查询
  220. /// </summary>
  221. /// <param name="pagedDto"></param>
  222. /// <param name="cancellationToken"></param>
  223. /// <returns></returns>
  224. public async Task<PagedDto<KnowledgeApplyHandlePageDto>> GetApplyHandleList(KnowledgeHandlePagedDto pagedDto, CancellationToken cancellationToken)
  225. {
  226. var (total, items) = await _knowledgeApplyRepository
  227. .Queryable()
  228. .Includes(it => it.User)
  229. .Includes(it => it.SystemOrganize)
  230. .Where(p => p.DepartmentId == _sessionContext.RequiredOrgId)
  231. .WhereIF(pagedDto.Status.HasValue, d => d.Status == pagedDto.Status)
  232. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.User.Name.Contains(pagedDto.Keyword!) || d.SystemOrganize.Name.Contains(pagedDto.Keyword!))
  233. .WhereIF(pagedDto.ApplyType.HasValue, d => d.KnowledgeApplyType == pagedDto.ApplyType)
  234. .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "0", d => d.IsOvertime == true)
  235. .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "1", d => d.IsOvertime == false)
  236. .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status != EKnowledgeApplyStatus.Failed && pagedDto.Status != EKnowledgeApplyStatus.Succeed, d => d.CreationTime >= pagedDto.StartTime)
  237. .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status != EKnowledgeApplyStatus.Failed && pagedDto.Status != EKnowledgeApplyStatus.Succeed, d => d.CreationTime <= pagedDto.EndTime)
  238. .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Failed, d => d.ReturnTime >= pagedDto.StartTime)
  239. .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Failed, d => d.ReturnTime <= pagedDto.EndTime)
  240. .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Succeed, d => d.HandleTime >= pagedDto.StartTime)
  241. .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Succeed, d => d.HandleTime <= pagedDto.EndTime)
  242. .OrderByDescending(p => p.CreationTime)
  243. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, cancellationToken);
  244. return new PagedDto<KnowledgeApplyHandlePageDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApplyHandlePageDto>>(items));
  245. }
  246. //public async Task<Dictionary<string, Stream>> KnowledgeInfoListExportAsync(KnowledgeInfoExportInDto dto, CancellationToken cancellationToken)
  247. //{
  248. // var streamList = new Dictionary<string, Stream>();
  249. // var knowList = await _knowledgeRepository.Queryable()
  250. // .Where(m => dto.Ids.Contains(m.Id))
  251. // .Select(m => new { m.Title, m.Content })
  252. // .ToListAsync(cancellationToken);
  253. // foreach (var item in knowList)
  254. // {
  255. // Stream stream = item.Content.HtmlToStream(dto.FileType);
  256. // streamList.Add(item.Title + dto.FileType.GetFileExtension(), stream);
  257. // }
  258. // return streamList;
  259. //}
  260. public async Task<Dictionary<string, Stream>> KnowledgeInfoListExportAsync(KnowledgeInfoExportInDto dto, CancellationToken cancellationToken)
  261. {
  262. var streamList = new Dictionary<string, Stream>();
  263. var knowList = await _knowledgeRepository.Queryable()
  264. .Where(m => dto.Ids.Contains(m.Id))
  265. .Select(m => new { m.Title, m.Content })
  266. .ToListAsync(cancellationToken);
  267. var tasks = knowList.Select(async item =>
  268. {
  269. var stream = await Task.Run(() => item.Content.HtmlToStream(dto.FileType, item.Title, _pdfManager), cancellationToken);
  270. return new KeyValuePair<string, Stream>(
  271. item.Title + dto.FileType.GetFileExtension(),
  272. stream
  273. );
  274. });
  275. var results = await Task.WhenAll(tasks);
  276. foreach (var kvp in results)
  277. {
  278. if (!streamList.ContainsKey(kvp.Key))
  279. {
  280. streamList.Add(kvp.Key, kvp.Value);
  281. }
  282. }
  283. return streamList;
  284. }
  285. public async Task<IList<KnowledgeWordOutDto>> TitleParticiple(string title)
  286. {
  287. var keywords = new List<KnowledgeWordOutDto>();
  288. var splitWords = new Segment().DoSegment(title);
  289. for (int i = 0; i < splitWords.Count; i++)
  290. {
  291. var word = splitWords.ElementAt(i);
  292. if (word is not { WordType: WordType.SimplifiedChinese, Word.Length: > 1 }) continue;
  293. var tag = splitWords.ElementAt(i).Word;
  294. var entity = await _knowledgeWordRepository.Queryable().Where(m => m.Tag == tag).FirstAsync();
  295. if (entity is not null)
  296. {
  297. keywords.Add(new KnowledgeWordOutDto(entity.Id, entity.Tag));
  298. continue;
  299. }
  300. var wordEntity = new KnowledgeWord
  301. {
  302. Tag = tag,
  303. Classify = "普通标签",
  304. Remark = "系统自动从知识标题分词",
  305. Synonym = "",
  306. IsEnable = 0
  307. };
  308. var keyId = await _knowledgeWordRepository.AddAsync(wordEntity);
  309. keywords.Add(new KnowledgeWordOutDto(keyId, tag));
  310. }
  311. return keywords;
  312. }
  313. public async Task<(int, IList<PageViewOutDto>)> GetPageViewListAsync(PageViewInDto dto, CancellationToken requestAborted = default)
  314. {
  315. var typeSpliceName = string.Empty;
  316. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  317. {
  318. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  319. typeSpliceName = type?.SpliceName;
  320. }
  321. var query = _knowledgePvepository.Queryable(includeDeleted: true)
  322. .LeftJoin<KnowledgeBase.Knowledge>((p, k) => p.KnowledgeCode == k.Code)
  323. .LeftJoin<KnowledgeRelationType>((p, k, r) => r.KnowledgeId == k.Id)
  324. .WhereIF(dto.Title.NotNullOrEmpty(), (p, k, r) => k.Title.Contains(dto.Title))
  325. .WhereIF(dto.CreatorName.NotNullOrEmpty(), (p, k, r) => p.CreatorName.Contains(dto.CreatorName))
  326. .WhereIF(dto.KnowledgeTypeId.NotNullOrEmpty(), (p, k, r) => r.KnowledgeTypeSpliceName.StartsWith(typeSpliceName))
  327. .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, (p, k, r) => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
  328. .OrderByDescending((p, k, r) => p.CreationTime);
  329. if (_sessionContext.OrgIsCenter == false)
  330. query = query.Where((p, k, r) => p.CreatorOrgId.StartsWith(_sessionContext.OrgId));
  331. return await query.Select<PageViewOutDto>().ToPagedListAsync(dto.PageIndex, dto.PageSize, requestAborted);
  332. }
  333. public async Task<(int total, IList<KnowledgeHotWordOutDto> items)> GetKnowledgeHotWordListAsync(KnowledgeHotWordInDto dto, CancellationToken requestAborted)
  334. {
  335. var query = _knowledgeHotWordRepository.Queryable()
  336. .WhereIF(dto.IsEnable != null, m => m.IsEnable == dto.IsEnable)
  337. .WhereIF(dto.KeyWord.NotNullOrEmpty(), m => m.KeyWord.Contains(dto.KeyWord))
  338. .WhereIF(dto.Type != null, m => m.Type == dto.Type)
  339. // .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, m => m.CreationTime >= dto.StartTime && m.CreationTime <= dto.EndTime)
  340. ;
  341. if (dto.SortField.NotNullOrEmpty())
  342. query = query.OrderByPropertyName(dto.SortField, (OrderByType)dto.OrderByType);
  343. else
  344. {
  345. query = query.OrderByDescending(m => m.Sort);
  346. query = query.OrderByDescending(m => m.CreationTime);
  347. }
  348. return await query.Select<KnowledgeHotWordOutDto>().ToPagedListAsync(dto.PageIndex, dto.PageSize, requestAborted);
  349. }
  350. public async Task UpdateKnowledgeHotWordAsync(UpdateKnowledgeHotWordInDto dto, CancellationToken requestAborted)
  351. {
  352. var entity = await _knowledgeHotWordRepository.GetAsync(dto.Id)
  353. ?? throw UserFriendlyException.SameMessage("数据不存在");
  354. dto.Adapt(entity);
  355. await _knowledgeHotWordRepository.UpdateAsync(entity);
  356. }
  357. public async Task AddKnowledgeHotWordAsync(AddKnowledgeHotWordInDto dto, CancellationToken requestAborted)
  358. {
  359. var isExist = await _knowledgeHotWordRepository.Queryable()
  360. .Where(m => m.KeyWord == dto.KeyWord).AnyAsync();
  361. if (isExist) throw UserFriendlyException.SameMessage("热词已存在");
  362. var entity = dto.Adapt<KnowledgeHotWord>();
  363. await _knowledgeHotWordRepository.AddAsync(entity, requestAborted);
  364. }
  365. public async Task<(int, List<KnowledgeRetrievalDataDto>)> KnowRetrievalAsync(KnowledgeRetrievalPagedListDto dto)
  366. {
  367. var typeSpliceName = string.Empty;
  368. var hotspotHotSpotFullName = string.Empty;
  369. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  370. {
  371. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  372. typeSpliceName = type?.SpliceName;
  373. }
  374. if (!string.IsNullOrEmpty(dto.HotspotId))
  375. {
  376. var hotspot = await _hotspotTypeRepository.GetAsync(x => x.Id == dto.HotspotId);
  377. hotspotHotSpotFullName = hotspot?.HotSpotFullName;
  378. }
  379. if (!_sessionContext.OrgIsCenter)
  380. {
  381. dto.Attribution = "部门知识库";
  382. }
  383. var query = _knowledgeRepository.Queryable(false, false, false);
  384. if (!_sessionContext.OrgIsCenter)
  385. query.Where(x => x.KnowledgeTypes.Any(t => t.Orgs.Any(to => to.Id == _sessionContext.RequiredOrgId)));
  386. var sugar = query
  387. .Includes(x => x.User)
  388. .Includes(x => x.SystemOrganize)
  389. .Includes(x => x.HotspotType)
  390. .Includes(x => x.KnowledgeType)
  391. .Where(x => x.IsDeleted == false)
  392. .Where(x => x.Status == EKnowledgeStatus.OnShelf)
  393. .Where(x => SqlFunc.HasValue(x.ExpiredTime) == false || x.ExpiredTime > DateTime.Now)
  394. //.Where(x => x.KnowledgeType.Any(t => t.KnowledgeType.KnowledgeTypeOrgs.Any(to => to.OrgId == _sessionContext.RequiredOrgId)
  395. // || t.KnowledgeType.KnowledgeTypeOrgs.Any() == false))
  396. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.StartsWith(typeSpliceName)))
  397. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeTypes.Any(t => t.SpliceName.StartsWith(typeSpliceName)))
  398. .WhereIF(!string.IsNullOrEmpty(hotspotHotSpotFullName), x => x.HotspotType.HotSpotFullName.EndsWith(hotspotHotSpotFullName!))
  399. .WhereIF(!string.IsNullOrEmpty(dto.HotspotName), x => x.HotspotType.HotSpotFullName.EndsWith(dto.HotspotName!))
  400. .WhereIF(!string.IsNullOrEmpty(dto.CreateOrgId), x => x.CreatorOrgId != null && x.CreatorOrgId.EndsWith(dto.CreateOrgId!))
  401. .WhereIF(!string.IsNullOrEmpty(dto.Attribution), x => x.Attribution == dto.Attribution!);
  402. if (dto.Keyword.NotNullOrEmpty())
  403. {
  404. var keywords = dto.Keyword!.SplitKeywords();
  405. var exp = Expressionable.Create<KnowledgeBase.Knowledge>();
  406. foreach (var keyword in keywords)
  407. {
  408. if (_appOptions.Value.IsZiGong)
  409. {
  410. //自贡任务 359 泸州自贡通用-调整知识检索时,多关键词组合查询的查询方式
  411. if (dto.RetrievalType == EKnowledgeRetrievalType.All)
  412. exp.And(x => x.Title.Contains(keyword) || x.Content.Contains(keyword));
  413. if (dto.RetrievalType == EKnowledgeRetrievalType.Title)
  414. exp.And(x => x.Title.Contains(keyword));
  415. if (dto.RetrievalType == EKnowledgeRetrievalType.Content)
  416. exp.And(x => x.Content.Contains(keyword));
  417. if (dto.RetrievalType == EKnowledgeRetrievalType.Summary)
  418. exp.And(x => x.Summary != null && x.Summary.Contains(keyword));
  419. if (dto.RetrievalType == EKnowledgeRetrievalType.KeyWord)
  420. {
  421. var keywordEntity = await _knowledgeWordRepository.GetAsync(m => m.Tag == keyword && m.IsEnable == 1);
  422. if (keywordEntity is null) continue;
  423. exp.And(x => SqlFunc.JsonArrayAny(x.Keywords, keywordEntity.Id));
  424. }
  425. }
  426. else
  427. {
  428. if (dto.RetrievalType == EKnowledgeRetrievalType.All)
  429. exp.Or(x => x.Title.Contains(keyword) || x.Content.Contains(keyword));
  430. if (dto.RetrievalType == EKnowledgeRetrievalType.Title)
  431. exp.Or(x => x.Title.Contains(keyword));
  432. if (dto.RetrievalType == EKnowledgeRetrievalType.Content)
  433. exp.Or(x => x.Content.Contains(keyword));
  434. if (dto.RetrievalType == EKnowledgeRetrievalType.Summary)
  435. exp.Or(x => x.Summary != null && x.Summary.Contains(keyword));
  436. if (dto.RetrievalType == EKnowledgeRetrievalType.KeyWord)
  437. {
  438. var keywordEntity = await _knowledgeWordRepository.GetAsync(m => m.Tag == keyword && m.IsEnable == 1);
  439. if (keywordEntity is null) continue;
  440. exp.Or(x => SqlFunc.JsonArrayAny(x.Keywords, keywordEntity.Id));
  441. }
  442. }
  443. }
  444. sugar = sugar.Where(exp.ToExpression());
  445. }
  446. if (dto.Content.NotNullOrEmpty())
  447. {
  448. var keywords = dto.Content!.GetSegment();
  449. var exp = Expressionable.Create<KnowledgeBase.Knowledge>();
  450. _knowledgeWordRepository.Queryable()
  451. .Where(m => keywords.Contains(m.Tag) && m.IsEnable == 1)
  452. .Select(m => m.Id)
  453. .ToList()
  454. .ForEach(m =>
  455. exp.Or(x => SqlFunc.JsonArrayAny(x.Keywords, m))
  456. );
  457. sugar = sugar.Where(exp.ToExpression());
  458. }
  459. switch (dto.Sort)
  460. {
  461. case "2":
  462. sugar = sugar.OrderByDescending(p => p.CollectCount);
  463. break;
  464. case "3":
  465. sugar = sugar.OrderByDescending(p => p.CreationTime);
  466. break;
  467. default:
  468. sugar = sugar.OrderByDescending(p => p.PageView);
  469. break;
  470. }
  471. return await sugar.Select<KnowledgeRetrievalDataDto>().ToPagedListAsync(dto.PageIndex, dto.PageSize);
  472. }
  473. public ISugarQueryable<KnowedgeStatisticsDto> GetKnowedgeStatistics(PagedKeywordRequest dto)
  474. {
  475. return _knowledgeRepository.Queryable()
  476. .Includes(p => p.SourceOrganize)
  477. .WhereIF(dto.StartTime.HasValue, p => p.LastModificationTime >= dto.StartTime)
  478. .WhereIF(dto.EndTime.HasValue, p => p.LastModificationTime <= dto.EndTime)
  479. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.SourceOrganize.Name.Contains(dto.Keyword))
  480. // .GroupBy(p => new { p.SourceOrganize.Name, p.LastModificationTime })
  481. .Select(p => new KnowedgeStatisticsDto
  482. {
  483. // Index = SqlFunc.RowNumber($"{p.LastModificationTime} desc "),\
  484. Index= SqlFunc.RowNumber($"{p.LastModificationTime} desc ", $"{p.SourceOrganize.Name}"),
  485. LastModificationTime = p.LastModificationTime,
  486. OrgName = p.SourceOrganize.Name
  487. })
  488. .MergeTable()
  489. .Where(p => p.Index == 1)
  490. .OrderByDescending(p => p.LastModificationTime);
  491. }
  492. }
  493. }