KnowledgeController.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. using Hotline.Api.Filter;
  2. using Hotline.Application.FlowEngine;
  3. using Hotline.Application.Knowledge;
  4. using Hotline.File;
  5. using Hotline.FlowEngine.WorkflowModules;
  6. using Hotline.KnowledgeBase;
  7. using Hotline.KnowledgeBase.Notifies;
  8. using Hotline.Permissions;
  9. using Hotline.Repository.SqlSugar.Extensions;
  10. using Hotline.Repository.SqlSugar.Ts;
  11. using Hotline.Settings;
  12. using Hotline.Settings.Hotspots;
  13. using Hotline.Share.Dtos;
  14. using Hotline.Share.Dtos.File;
  15. using Hotline.Share.Dtos.FlowEngine;
  16. using Hotline.Share.Dtos.Knowledge;
  17. using Hotline.Share.Enums.KnowledgeBase;
  18. using Hotline.Users;
  19. using MapsterMapper;
  20. using MediatR;
  21. using Microsoft.AspNetCore.Mvc;
  22. using SqlSugar;
  23. using XF.Domain.Authentications;
  24. using XF.Domain.Exceptions;
  25. using XF.Domain.Repository;
  26. using XF.Utility.EnumExtensions;
  27. namespace Hotline.Api.Controllers
  28. {
  29. public class KnowledgeController : BaseController
  30. {
  31. #region 注入
  32. private readonly IKnowledgeRepository _knowledgeRepository;
  33. private readonly ISessionContext _sessionContext;
  34. private readonly IKnowledgeDomainService _knowledgeDomainService;
  35. private readonly IMapper _mapper;
  36. private readonly IKnowApplication _knowApplication;
  37. private readonly IMediator _mediator;
  38. private readonly IWorkflowApplication _workflowApplication;
  39. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  40. private readonly IRepository<User> _userRepository;
  41. private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
  42. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  43. private readonly IRepositoryTextSearch<KnowledgeTs> _repositoryts;
  44. private readonly IRepository<KnowledgeWord> _knowledgeWrodRepository;
  45. private readonly IRepository<KnowledgeQuestions> _knowledgeQuestionsRepository;
  46. private readonly IRepository<KnowledgeCorrection> _knowledgeCorrectionRepository;
  47. private readonly IRepository<KnowledgeCollect> _knowledgeCollectRepository;
  48. private readonly ISystemDomainService _systemDomainService;
  49. private readonly IRepository<KnowledgeComment> _knowledgeCommentRepository;
  50. private readonly ISystemOrganizeRepository _systemOrganizeRepository;
  51. private readonly IFileRepository _fileRepository;
  52. public KnowledgeController(
  53. IKnowledgeRepository knowledgeRepository,
  54. ISessionContext sessionContext,
  55. IKnowledgeDomainService knowledgeDomainService,
  56. IMapper mapper,
  57. IKnowApplication knowApplication,
  58. IMediator mediator,
  59. IWorkflowApplication workflowApplication,
  60. IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
  61. IRepository<User> userRepository,
  62. IRepository<KnowledgeType> knowledgeTypeRepository,
  63. IRepository<Hotspot> hotspotTypeRepository,
  64. IRepositoryTextSearch<KnowledgeTs> repositoryts,
  65. IRepository<KnowledgeWord> knowledgeWrodRepository,
  66. IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
  67. IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
  68. IRepository<KnowledgeCollect> knowledgeCollectRepository,
  69. ISystemDomainService systemDomainService,
  70. IRepository<KnowledgeComment> knowledgeCommentRepository,
  71. ISystemOrganizeRepository systemOrganizeRepository,
  72. IFileRepository fileRepository
  73. )
  74. {
  75. _knowledgeRepository = knowledgeRepository;
  76. _sessionContext = sessionContext;
  77. _knowledgeDomainService = knowledgeDomainService;
  78. _mapper = mapper;
  79. _knowApplication = knowApplication;
  80. _mediator = mediator;
  81. _workflowApplication = workflowApplication;
  82. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  83. _userRepository = userRepository;
  84. _knowledgeTypeRepository = knowledgeTypeRepository;
  85. _hotspotTypeRepository = hotspotTypeRepository;
  86. _repositoryts = repositoryts;
  87. _knowledgeWrodRepository = knowledgeWrodRepository;
  88. _knowledgeQuestionsRepository = knowledgeQuestionsRepository;
  89. _knowledgeCorrectionRepository = knowledgeCorrectionRepository;
  90. _knowledgeCollectRepository = knowledgeCollectRepository;
  91. _systemDomainService = systemDomainService;
  92. _knowledgeCommentRepository = knowledgeCommentRepository;
  93. _systemOrganizeRepository = systemOrganizeRepository;
  94. _fileRepository = fileRepository;
  95. }
  96. #endregion
  97. #region 知识管理
  98. /// <summary>
  99. /// 知识库-新增
  100. /// </summary>
  101. /// <param name="dto"></param>
  102. /// <returns></returns>
  103. [Permission(EPermission.AddKnowledge)]
  104. [HttpPost("add")]
  105. [LogFilter("知识新增")]
  106. public async Task<string> AddKnowledge([FromBody] AddStartFlowDto dto)
  107. {
  108. //var addDto = _mapper.Map<AddKnowledgeDto>(dto.Data);
  109. var kn = _mapper.Map<Knowledge>(dto.Data);
  110. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == kn.Title).AnyAsync();
  111. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  112. //Code为空,从新生成Code
  113. if (string.IsNullOrEmpty(kn.Code))
  114. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  115. kn.Status = EKnowledgeStatus.Drafts;
  116. kn.InitId();
  117. if (dto.Data.Files.Any()) kn.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, kn.Id, "", HttpContext.RequestAborted);
  118. await _knowledgeRepository.AddAsync(kn, HttpContext.RequestAborted);
  119. if (dto.Workflow != null && !string.IsNullOrEmpty(kn.Id))
  120. {
  121. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  122. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  123. startDto.Title = "知识库新增";
  124. await StartFlow(kn.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  125. var knowledge = await _knowledgeRepository.GetAsync(kn.Id);
  126. knowledge.Status = EKnowledgeStatus.Auditing;
  127. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  128. }
  129. return kn.Id;
  130. }
  131. /// <summary>
  132. /// 知识库-知识下架
  133. /// </summary>
  134. /// <param name="Id"></param>
  135. /// <returns></returns>
  136. [Permission(EPermission.KnowledgeOffShelf)]
  137. [HttpPut("offshelf")]
  138. [LogFilter("知识下架")]
  139. public async Task KnowledgeOffShelf(string Id)
  140. {
  141. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  142. if (know != null && know.Status == EKnowledgeStatus.OnShelf)
  143. {
  144. know.Status = EKnowledgeStatus.OffShelf;
  145. know.OnShelfTime = null;
  146. know.OffShelfTime = DateTime.Now;
  147. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  148. }
  149. else
  150. throw UserFriendlyException.SameMessage("知识下架失败");
  151. }
  152. /// <summary>
  153. /// 知识库-知识上架
  154. /// </summary>
  155. /// <param name="Id"></param>
  156. /// <returns></returns>
  157. [Permission(EPermission.KnowledgeOnTheShelf)]
  158. [HttpPut("ontheshelf")]
  159. [LogFilter("知识上架")]
  160. public async Task KnowledgeOnTheShelf(string Id)
  161. {
  162. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  163. if (know != null && know.Status == EKnowledgeStatus.OffShelf)
  164. {
  165. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == know.Title && x.Id != know.Id).AnyAsync();
  166. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  167. if (know.ExpiredTime < DateTime.Now) throw UserFriendlyException.SameMessage("知识已过期不能上架!");
  168. know.Status = EKnowledgeStatus.OnShelf;
  169. know.OnShelfTime = DateTime.Now;
  170. know.OffShelfTime = null;
  171. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  172. }
  173. else
  174. throw UserFriendlyException.SameMessage("知识上架失败");
  175. }
  176. /// <summary>
  177. /// 知识库-标题
  178. /// </summary>
  179. /// <param name="title"></param>
  180. /// <returns></returns>
  181. [HttpGet("title")]
  182. public async Task<bool> KnowledgeTitle([FromQuery] KnowledgeTitleDto dto)
  183. {
  184. var count = await _knowledgeRepository.Queryable()
  185. .WhereIF(!string.IsNullOrEmpty(dto.Id), x => x.Id != dto.Id)
  186. .Where(x => x.Title == dto.Title && x.Status == EKnowledgeStatus.OnShelf).CountAsync();
  187. return count > 0;
  188. }
  189. /// <summary>
  190. /// 知识库-修改
  191. /// </summary>
  192. /// <param name="dto"></param>
  193. /// <returns></returns>
  194. [HttpPut("update")]
  195. [LogFilter("知识修改")]
  196. public async Task UpdateKnowledge([FromBody] UpdateStartFlowDto dto)
  197. {
  198. var update = _mapper.Map<UpdateKnowledgeDto>(dto.Data);
  199. var knowledge = await _knowledgeRepository.GetAsync(update.Id);
  200. if (knowledge == null)
  201. throw UserFriendlyException.SameMessage("知识库数据错误");
  202. if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
  203. throw UserFriendlyException.SameMessage("知识库数据不可修改");
  204. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == update.Title && x.Id != update.Id).AnyAsync();
  205. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  206. _mapper.Map(dto.Data, knowledge);
  207. //if (update.Tags.Any()) await _repositoryts.UpdateVectorAsync(update.Id, update.Tags, HttpContext.RequestAborted);
  208. if (dto.Data.Files.Any()) knowledge.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, knowledge.Id, "", HttpContext.RequestAborted);
  209. if (dto.Workflow != null) knowledge.Renewaln = update.Status != EKnowledgeStatus.Drafts;
  210. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  211. if (dto.Workflow != null)
  212. {
  213. if (update.Status == EKnowledgeStatus.Drafts)
  214. {
  215. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  216. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  217. startDto.Title = "知识库新增";
  218. await StartFlow(update.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  219. }
  220. else
  221. {
  222. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  223. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeUpdate;
  224. startDto.Title = "知识库修改";
  225. await StartFlow(update.Id, WorkflowModuleConsts.KnowledgeUpdate, EKnowledgeApplyType.Update, startDto);
  226. }
  227. }
  228. }
  229. /// <summary>
  230. /// 删除知识
  231. /// </summary>
  232. /// <param name="id"></param>
  233. /// <returns></returns>
  234. [HttpDelete]
  235. [LogFilter("删除知识")]
  236. public async Task Remove([FromBody] DeleteStartFlowDto dto)
  237. {
  238. var delete = _mapper.Map<KnowledgeDto>(dto.Data);
  239. var knowledge = await _knowledgeRepository.GetAsync(delete.Id, HttpContext.RequestAborted);
  240. if (knowledge == null)
  241. throw UserFriendlyException.SameMessage("无效知识库数据");
  242. if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
  243. throw UserFriendlyException.SameMessage("知识库数据不可删除");
  244. if (knowledge.Status == EKnowledgeStatus.Drafts)
  245. {
  246. await _knowledgeRepository.RemoveAsync(knowledge, false, HttpContext.RequestAborted);
  247. }
  248. else
  249. {
  250. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  251. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeDelete;
  252. startDto.Title = "知识库删除";
  253. await StartFlow(delete.Id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, startDto);
  254. }
  255. }
  256. /// <summary>
  257. /// 增加搜索量
  258. /// </summary>
  259. /// <param name="dto"></param>
  260. /// <returns></returns>
  261. [HttpPost("search_num")]
  262. [LogFilter("知识搜索")]
  263. public async Task SearchNum([FromBody] KnowledgeSearchNumDto dto)
  264. {
  265. var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  266. if (knowledge == null)
  267. throw UserFriendlyException.SameMessage("无效知识库数据");
  268. knowledge.SearchNum++;
  269. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  270. }
  271. /// <summary>
  272. /// 搜索量列表
  273. /// </summary>
  274. /// <param name="dto"></param>
  275. /// <returns></returns>
  276. [HttpGet("search_num/list")]
  277. public async Task<PagedDto<KnowledgeDto>> SearchNumList([FromQuery] KnowledgeCollectListDto dto)
  278. {
  279. var (total, items) = await _knowledgeRepository.Queryable(false,false,false)
  280. .Where(x => x.Status == EKnowledgeStatus.OnShelf)
  281. .Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  282. .OrderByDescending(x => x.SearchNum)
  283. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  284. return new PagedDto<KnowledgeDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDto>>(items));
  285. }
  286. /// <summary>
  287. /// 知识库-知识修改-查询详情
  288. /// </summary>
  289. /// <param name="Id"></param>
  290. /// <returns></returns>
  291. [HttpGet("updateinfo/{Id}")]
  292. public async Task<KnowledgeInfoDto> KnowledgeUpdateInfo(string Id)
  293. {
  294. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  295. if (know is null)
  296. throw UserFriendlyException.SameMessage("知识查询失败!");
  297. var knowledgeInfoDto = _mapper.Map<KnowledgeInfoDto>(know);
  298. //分类
  299. //var type = await _knowledgeTypeRepository.GetAsync(know.KnowledgeTypeId, HttpContext.RequestAborted);
  300. //if (type != null)
  301. // knowledgeInfoDto.KnowledgeTypeName = type.SpliceName;
  302. //热点
  303. var hot = await _hotspotTypeRepository.GetAsync(know.HotspotId, HttpContext.RequestAborted);
  304. if (hot != null)
  305. knowledgeInfoDto.HotspotName = hot.HotSpotFullName;
  306. //收藏
  307. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  308. if (collect != null)
  309. knowledgeInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  310. return knowledgeInfoDto;
  311. }
  312. /// <summary>
  313. /// 知识库-查询详情-增加浏览量
  314. /// </summary>
  315. /// <param name="Id">知识Id</param>
  316. /// <param name="IsAddPv">默认不增加,false不增加,true增加浏览量</param>
  317. /// <returns></returns>
  318. [HttpGet("info/{Id}")]
  319. public async Task<KnowledgeInfoDto> KnowledgeInfo(string Id, bool? IsAddPv)
  320. {
  321. var knowledge = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
  322. if (knowledge is null)
  323. throw UserFriendlyException.SameMessage("知识查询失败!");
  324. if (knowledge.Workflow != null ) knowledge.IsCanHandle = knowledge.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
  325. //转化
  326. var knowledgeShowInfoDto = _mapper.Map<KnowledgeInfoDto>(knowledge);
  327. //var type = await _knowledgeTypeRepository.GetAsync(knowledge.KnowledgeTypeId, HttpContext.RequestAborted);
  328. //if (type != null)
  329. //{
  330. // knowledgeShowInfoDto.KnowledgeTypeName = type.SpliceName;
  331. // knowledgeShowInfoDto.KnowledgeType = _mapper.Map<KnowledgeTypeDto>(type);
  332. //}
  333. var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
  334. if (hot != null)
  335. knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
  336. //收藏
  337. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  338. if (collect != null)
  339. knowledgeShowInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  340. //关联知识
  341. var knowledges = await _knowledgeRepository.Queryable().In(x => x.Id, knowledge.Knowledges).Where(x=>x.Status == EKnowledgeStatus.OnShelf &&((x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)).ToListAsync();
  342. if (knowledges.Any())
  343. knowledgeShowInfoDto.KnowledgeDtos = _mapper.Map<List<KnowledgeDto>>(knowledges);
  344. //关键词
  345. var knowledgeWords = await _knowledgeWrodRepository.Queryable().In(x => x.Id, knowledge.Keywords).ToListAsync();
  346. if (knowledgeWords.Any())
  347. knowledgeShowInfoDto.KeywordsDto = _mapper.Map<List<KnowledgeWordDto>>(knowledgeWords);
  348. var files = await _fileRepository.Queryable().Where(x => x.Key == knowledge.Id).ToListAsync();
  349. if (files.Any()) knowledgeShowInfoDto.Files = _mapper.Map<List<FileDto>>(files);
  350. if (IsAddPv == true)
  351. _mediator.Publish(new GetKnowledgeInfoNotify(knowledge));
  352. return knowledgeShowInfoDto;
  353. }
  354. /// <summary>
  355. /// 知识申请-关联知识-获取知识列表
  356. /// </summary>
  357. /// <returns></returns>
  358. [HttpGet("getknowledge")]
  359. public async Task<IReadOnlyList<KnowledgeCreateBMDataDto>> GetKnowledge()
  360. {
  361. var temp = await _knowledgeRepository
  362. .Queryable()
  363. .LeftJoin<SystemOrganize>((o, sys) => o.CreatorOrgId == sys.Id)
  364. //重新构建数据
  365. .Select((o, sys) => new
  366. {
  367. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  368. DepartmentId = sys.Id,
  369. Department = sys.Name,
  370. o.Id,
  371. o.Title,
  372. o.Status,
  373. o.Code,
  374. o.IsDeleted,
  375. o.ExpiredTime
  376. })
  377. //将结果合并成一个表
  378. .MergeTable()
  379. //取第一条数据
  380. .Where(x=>x.IsDeleted ==false )
  381. .Where(x=> (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  382. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  383. .ToListAsync();
  384. //返回数据
  385. return _mapper.Map<IReadOnlyList<KnowledgeCreateBMDataDto>>(temp);
  386. }
  387. /// <summary>
  388. /// 我的草稿箱
  389. /// </summary>
  390. /// <param name="pagedDto"></param>
  391. /// <returns></returns>
  392. [HttpGet("mydraftslist")]
  393. public async Task<PagedDto<KnowledgeDataDto>> MyDraftsList([FromQuery] MyDraftsListPagedDto pagedDto)
  394. {
  395. var (total, items) = await _knowledgeRepository
  396. .Queryable()
  397. .Includes(it => it.User)
  398. .Where(p => p.CreatorId == _sessionContext.RequiredUserId && p.Status == EKnowledgeStatus.Drafts)
  399. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  400. .WhereIF(pagedDto.StartTime != null, d => d.CreationTime >= pagedDto.StartTime)
  401. .WhereIF(pagedDto.EndTime != null, d => d.CreationTime <= pagedDto.EndTime)
  402. .OrderByDescending(p => p.CreationTime)
  403. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  404. return new PagedDto<KnowledgeDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(items));
  405. }
  406. /// <summary>
  407. /// 知识库列表页面枚举值
  408. /// </summary>
  409. /// <returns></returns>
  410. [HttpGet("knowledge-status-data")]
  411. public async Task<object> KnowledgeStatus()
  412. {
  413. return new List<KeyValuePair<int, string>>
  414. {
  415. new KeyValuePair<int, string>(1, "审核中"),
  416. new KeyValuePair<int, string>(3, "已上架"),
  417. new KeyValuePair<int, string>(4, "已下架")
  418. };
  419. }
  420. /// <summary>
  421. /// 知识查询
  422. /// </summary>
  423. /// <param name="pagedDto"></param>
  424. /// <returns></returns>
  425. [HttpGet]
  426. public async Task<PagedDto<KnowledgeDataDto>> GetKnowList([FromQuery] KnowPagedListDto pagedDto)
  427. {
  428. var typeSpliceName = string.Empty;
  429. var hotspotHotSpotFullName = string.Empty;
  430. if (!string.IsNullOrEmpty(pagedDto.HotspotId))
  431. {
  432. var hotspot = await _hotspotTypeRepository.GetAsync(x => x.Id == pagedDto.HotspotId);
  433. hotspotHotSpotFullName = hotspot?.HotSpotFullName;
  434. }
  435. var aa = _knowledgeRepository.Queryable().OrderByDescending(d => d.CreationTime).ToSql();
  436. var (total, temp) = await _knowledgeRepository.Queryable(false,false,false)
  437. .Includes(x => x.User)
  438. .Includes(x => x.SystemOrganize)
  439. .Includes(x => x.SourceOrganize)
  440. .Includes(x => x.HotspotType)
  441. .Includes(x=>x.Workflow)
  442. .Where(x => x.IsDeleted == false)
  443. .Where(x => (x.Status == EKnowledgeStatus.Drafts && x.CreatorId == _sessionContext.UserId) || (x.Status != EKnowledgeStatus.Drafts))
  444. .WhereIF(!string.IsNullOrEmpty(pagedDto.Title), x => x.Title.Contains(pagedDto.Title!))
  445. .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!))
  446. .WhereIF(pagedDto.Status.HasValue && pagedDto.Status != EKnowledgeStatus.OffShelf, x => x.Status == pagedDto.Status && ((x.ExpiredTime != null && x.ExpiredTime > DateTime.Now) || x.ExpiredTime == null))
  447. .WhereIF(pagedDto.Status.HasValue && pagedDto.Status == EKnowledgeStatus.OffShelf, x => x.Status == pagedDto.Status || (x.ExpiredTime != null && x.ExpiredTime < DateTime.Now && x.Status != EKnowledgeStatus.Drafts))
  448. .WhereIF(pagedDto.IsPublic.HasValue, x => x.IsPublic == pagedDto.IsPublic)
  449. .WhereIF(!string.IsNullOrEmpty(pagedDto.Summary), x => x.Summary != null && x.Summary.Contains(pagedDto.Summary!))
  450. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.KnowledgeType, typeSpliceName))
  451. .WhereIF(!string.IsNullOrEmpty(hotspotHotSpotFullName), x => x.HotspotType.HotSpotFullName.EndsWith(hotspotHotSpotFullName!))
  452. .WhereIF(!string.IsNullOrEmpty(pagedDto.CreateOrgId), x => x.CreatorOrgId != null && x.CreatorOrgId.EndsWith(pagedDto.CreateOrgId!))
  453. .OrderByDescending(d => d.CreationTime)
  454. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  455. //temp.ForEach(x => x.IsCanHandle = x.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId));
  456. //返回数据
  457. return new PagedDto<KnowledgeDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(temp));
  458. }
  459. /// <summary>
  460. /// 知识检索
  461. /// </summary>
  462. /// <param name="pagedDto"></param>
  463. /// <returns></returns>
  464. [HttpGet("knowretrieval")]
  465. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrieval([FromQuery] KnowledgeRetrievalPagedListDto pagedDto)
  466. {
  467. var typeSpliceName = string.Empty;
  468. var hotspotHotSpotFullName = string.Empty;
  469. if (!string.IsNullOrEmpty(pagedDto.KnowledgeTypeId))
  470. {
  471. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == pagedDto.KnowledgeTypeId);
  472. typeSpliceName = type?.SpliceName;
  473. }
  474. if (!string.IsNullOrEmpty(pagedDto.HotspotId))
  475. {
  476. var hotspot = await _hotspotTypeRepository.GetAsync(x => x.Id == pagedDto.HotspotId);
  477. hotspotHotSpotFullName = hotspot?.HotSpotFullName;
  478. }
  479. var sugar = _knowledgeRepository
  480. .Queryable(false,false,false)
  481. .Includes(x => x.User)
  482. .Includes(x => x.SystemOrganize)
  483. .Includes(x => x.HotspotType)
  484. .Where(x => x.IsDeleted == false)
  485. .Where(x=>x.Status == EKnowledgeStatus.OnShelf)
  486. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.All && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!) || d.Content.Contains(pagedDto.Keyword!))// || d.Additions.Contains(pagedDto.Keyword)
  487. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Title && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  488. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Content && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Content.Contains(pagedDto.Keyword!))
  489. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Summary && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Summary != null && d.Summary.Contains(pagedDto.Keyword!))
  490. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.KnowledgeType, typeSpliceName))
  491. .WhereIF(!string.IsNullOrEmpty(hotspotHotSpotFullName), x => x.HotspotType.HotSpotFullName.EndsWith(hotspotHotSpotFullName!))
  492. .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotName), x => x.HotspotType.HotSpotFullName.EndsWith(pagedDto.HotspotName!))
  493. .WhereIF(!string.IsNullOrEmpty(pagedDto.CreateOrgId), x => x.CreatorOrgId != null && x.CreatorOrgId.EndsWith(pagedDto.CreateOrgId!))
  494. .WhereIF(!string.IsNullOrEmpty(pagedDto.Attribution), x => x.Attribution == pagedDto.Attribution!);
  495. switch (pagedDto.Sort)
  496. {
  497. case "2":
  498. sugar = sugar.OrderByDescending(p => p.Score);
  499. break;
  500. case "3":
  501. sugar = sugar.OrderByDescending(p => p.CreationTime);
  502. break;
  503. default:
  504. sugar = sugar.OrderByDescending(p => p.PageView);
  505. break;
  506. }
  507. var (total, temp) = await sugar.ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  508. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  509. }
  510. #endregion
  511. #region 我的知识删除列表
  512. /// <summary>
  513. /// 我的知识删除列表页面枚举值
  514. /// </summary>
  515. /// <returns></returns>
  516. [HttpGet("delete-status-data")]
  517. public async Task<object> DeleteApplyStatus()
  518. {
  519. return EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>();
  520. }
  521. /// <summary>
  522. /// 我的知识删除列表
  523. /// </summary>
  524. /// <param name="pagedDto"></param>
  525. /// <returns></returns>
  526. [HttpGet("deletelist")]
  527. public async Task<PagedDto<KnowledgeDeleteApplyDataDto>> GetDeleteApplyList([FromQuery] KnowledgeDeletelPagedListDto pagedDto)
  528. {
  529. var (total, items) = await _knowledgeWorkFlowRepository
  530. .Queryable(includeDeleted: true)
  531. .Includes(it => it.Knowledge)
  532. .Includes(it => it.User)
  533. .Includes(it => it.SystemOrganize)
  534. .Includes(it => it.Knowledge, it => it.KnowledgeType)
  535. .Includes(it => it.Knowledge, it => it.HotspotType)
  536. .Includes(it => it.Workflow)
  537. .Where(d => d.CreatorId == _sessionContext.RequiredUserId && d.WorkflowModuleStatus == EKnowledgeApplyType.Delete && d.WorkflowId != null)
  538. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  539. .WhereIF(pagedDto.StartApplyTime.HasValue, d => d.CreationTime >= pagedDto.StartApplyTime)
  540. .WhereIF(pagedDto.EndApplyTime.HasValue, d => d.CreationTime <= pagedDto.EndApplyTime)
  541. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  542. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  543. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  544. .OrderByDescending(p => p.CreationTime)
  545. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  546. return new PagedDto<KnowledgeDeleteApplyDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDeleteApplyDataDto>>(items));
  547. }
  548. /// <summary>
  549. /// 审核管理页面枚举值
  550. /// </summary>
  551. /// <returns></returns>
  552. [HttpGet("approval-base-data")]
  553. public async Task<object> ApprovalBaseData()
  554. {
  555. return new
  556. {
  557. EKnowledgeWorkFlowStatus = EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>(),
  558. EKnowledgeApplyType = EnumExts.GetDescriptions<EKnowledgeApplyType>()
  559. };
  560. }
  561. /// <summary>
  562. /// 审核管理
  563. /// </summary>
  564. /// <param name="pagedDto"></param>
  565. /// <returns></returns>
  566. [HttpGet("approvedlist")]
  567. public async Task<PagedDto<KnowledgeApprovalDataDto>> ApprovedList([FromQuery] KnowledgeApprovalPagedListDto pagedDto)
  568. {
  569. var (total, items) = await _knowledgeWorkFlowRepository
  570. .Queryable(includeDeleted: true)
  571. .Includes(it => it.Knowledge)
  572. .Includes(it => it.User)
  573. .Includes(it => it.SystemOrganize)
  574. .Includes(it => it.Workflow)
  575. .Where(it => it.WorkflowId != null)
  576. .WhereIF(pagedDto.EKnowledgeApplyType.HasValue, d => d.WorkflowModuleStatus == pagedDto.EKnowledgeApplyType)
  577. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  578. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  579. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  580. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  581. .OrderByDescending(p => p.CreationTime)
  582. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  583. foreach (var item in items)
  584. {
  585. if (item.Workflow != null)
  586. item.CanHandle = item.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
  587. }
  588. //处理是否可以办理
  589. //items.ForEach(d => d.CanHandle = d.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgCode));
  590. return new PagedDto<KnowledgeApprovalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApprovalDataDto>>(items));
  591. }
  592. /// <summary>
  593. /// 工单受理知识检索
  594. /// </summary>
  595. /// <param name="pagedDto"></param>
  596. /// <returns></returns>
  597. [HttpGet("knowpopscreen")]
  598. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowPopScreen([FromQuery] KnowledgePopScreenPagedListDto pagedDto)
  599. {
  600. var orgid = string.Empty;
  601. if (pagedDto.RetrievalType == EKnowledgeRetrievalType.Org && !string.IsNullOrEmpty(pagedDto.Keyword))
  602. {
  603. var organize = await _systemOrganizeRepository.GetAsync(x => x.Name == pagedDto.Keyword);
  604. orgid = organize?.Id;
  605. }
  606. var (total, temp) = await _knowledgeRepository.Queryable()
  607. .Includes(x=>x.SourceOrganize)
  608. .Where(d => d.Status == EKnowledgeStatus.OnShelf)
  609. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Title && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  610. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Content && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Content.Contains(pagedDto.Keyword!))
  611. .WhereIF(!string.IsNullOrEmpty(orgid) && pagedDto.RetrievalType == EKnowledgeRetrievalType.Org, x=>x.CreatorOrgId.EndsWith(orgid!))
  612. .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotId), p => p.HotspotId == pagedDto.HotspotId)
  613. .OrderByDescending(p => p.CreationTime)
  614. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  615. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  616. }
  617. ///// <summary>
  618. ///// 新增-开始流程
  619. ///// </summary>
  620. ///// <param name="id">知识id</param>
  621. ///// <param name="dto">流程开启参数</param>
  622. ///// <returns></returns>
  623. //[Permission(EPermission.AddKnowledge)]
  624. //[HttpPost("{id}/add-startflow")]
  625. //public async Task AddStartFlow(string id, [FromBody] StartWorkflowDto dto)
  626. //{
  627. // await StartFlow(id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, dto);
  628. //}
  629. ///// <summary>
  630. ///// 删除-开始流程
  631. ///// </summary>
  632. ///// <param name="id">知识id</param>
  633. ///// <param name="dto">流程开启参数</param>
  634. ///// <returns></returns>
  635. //[Permission(EPermission.KnowledgeDelete)]
  636. //[HttpPost("{id}/remove-startflow")]
  637. //public async Task RemoveStartFlow(string id, [FromBody] StartWorkflowDto dto)
  638. //{
  639. // await StartFlow(id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, dto);
  640. //}
  641. /// <summary>
  642. /// 查询知识库办理流程开启参数-新增
  643. /// </summary>
  644. /// <returns></returns>
  645. //[Permission(EPermission.AddKnowledge)]
  646. [HttpGet("add-flow-start")]
  647. public async Task<NextStepsDto> GetAddFlowStartOptionsAsync()
  648. {
  649. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeAdd,
  650. HttpContext.RequestAborted);
  651. }
  652. /// <summary>
  653. /// 查询知识库办理流程开启参数-新增
  654. /// </summary>
  655. /// <returns></returns>
  656. //[Permission(EPermission.AddKnowledge)]
  657. [HttpGet("update-flow-start")]
  658. public async Task<NextStepsDto> GetUpdateFlowStartOptionsAsync()
  659. {
  660. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeUpdate,
  661. HttpContext.RequestAborted);
  662. }
  663. /// <summary>
  664. /// 查询知识库办理流程开启参数-删除
  665. /// </summary>
  666. /// <returns></returns>
  667. //[Permission(EPermission.KnowledgeDelete)]
  668. [HttpGet("remove-flow-start")]
  669. public async Task<NextStepsDto> GetRemoveFlowStartOptionsAsync()
  670. {
  671. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeDelete,
  672. HttpContext.RequestAborted);
  673. }
  674. /// <summary>
  675. /// 开始流程
  676. /// </summary>
  677. /// <param name="id">知识ID</param>
  678. /// <param name="moduleCode">知识模板编号</param>
  679. /// <param name="eKnowledgeApplyType">申请类型</param>
  680. /// <param name="dto">流程开启参数</param>
  681. /// <returns></returns>
  682. private async Task StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
  683. {
  684. var knowledge = await _knowledgeRepository.GetAsync(id, HttpContext.RequestAborted);
  685. if (knowledge == null)
  686. throw UserFriendlyException.SameMessage("无效知识编号");
  687. if (eKnowledgeApplyType == EKnowledgeApplyType.Delete)
  688. {
  689. if (knowledge.IsDeleted == true)
  690. throw UserFriendlyException.SameMessage("知识删除失败");
  691. ////验证是否已经发起过知识删除流程
  692. //var exists = await _knowledgeWorkFlowRepository.GetAsync(p => p.KnowledgeId == knowledge.Id && p.WorkflowModuleStatus == EKnowledgeApplyType.Delete
  693. //&& (p.WorkFlowApplyStatus == EKnowledgeWorkFlowStatus.Success || p.WorkFlowApplyStatus == EKnowledgeWorkFlowStatus.Auditing) && p.WorkflowId != null);
  694. //if (exists != null)
  695. // throw UserFriendlyException.SameMessage($"该知识已发起过{WorkflowModuleConsts.KnowledgeDelete}流程");//todo
  696. }
  697. //知识审批主表
  698. var flowId = await _knowledgeDomainService.AddWorkFlowAsync(id, eKnowledgeApplyType, HttpContext.RequestAborted);
  699. dto.DefinitionModuleCode = moduleCode;
  700. dto.Title = knowledge.Title;
  701. await _workflowApplication.StartWorkflowAsync(dto, flowId, cancellationToken: HttpContext.RequestAborted);
  702. }
  703. #endregion
  704. #region 知识库词库
  705. /// <summary>
  706. /// 新增知识库词库
  707. /// </summary>
  708. /// <param name="dtos"></param>
  709. /// <returns></returns>
  710. [Permission(EPermission.AddKnowledgeWord)]
  711. [HttpPost("knowledge_word")]
  712. [LogFilter("新增知识库词库")]
  713. public async Task Add([FromBody] KnowledgeWordAddDto dto)
  714. {
  715. var word = _mapper.Map<KnowledgeWord>(dto);
  716. await _knowledgeWrodRepository.AddAsync(word, HttpContext.RequestAborted);
  717. }
  718. /// <summary>
  719. /// 删除知识库词库
  720. /// </summary>
  721. /// <param name="dto"></param>
  722. /// <returns></returns>
  723. [Permission(EPermission.DeleteKnowledgeWord)]
  724. [HttpDelete("knowledge_word")]
  725. [LogFilter("删除知识库词库")]
  726. public async Task Delete([FromBody] KnowledgeWordDeleteDto dto)
  727. {
  728. await _knowledgeRepository.RemoveKnowledgeWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
  729. }
  730. /// <summary>
  731. /// 更新知识库词库
  732. /// </summary>
  733. /// <param name="dto"></param>
  734. /// <returns></returns>
  735. [Permission(EPermission.UpdateKnowledgeWord)]
  736. [HttpPut("knowledge_word")]
  737. [LogFilter("更新知识库词库")]
  738. public async Task Update([FromBody] KnowledgeWordUpdateDto dto)
  739. {
  740. var word = await _knowledgeWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  741. if (word is null)
  742. throw UserFriendlyException.SameMessage("无效知识库词库");
  743. _mapper.Map(dto, word);
  744. word.LastModificationName = _sessionContext.UserName;
  745. await _knowledgeWrodRepository.UpdateAsync(word, HttpContext.RequestAborted);
  746. }
  747. /// <summary>
  748. /// 获取知识库词库列表
  749. /// </summary>
  750. /// <param name="dto"></param>
  751. /// <returns></returns>
  752. [Permission(EPermission.KnowledgeWordList)]
  753. [HttpGet("knowledge_word/list")]
  754. public async Task<PagedDto<KnowledgeWordDto>> List([FromQuery] KnowledgeWordListDto dto)
  755. {
  756. var (total, items) = await _knowledgeWrodRepository.Queryable()
  757. .WhereIF(!string.IsNullOrEmpty(dto.Tag), x => x.Tag == dto.Tag!)
  758. .WhereIF(!string.IsNullOrEmpty(dto.Classify), x => x.Classify == dto.Classify!)
  759. .WhereIF(!string.IsNullOrEmpty(dto.Synonym), x => x.Synonym != null && x.Synonym.Contains(dto.Synonym!))
  760. .OrderByDescending(x => x.CreationTime)
  761. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  762. return new PagedDto<KnowledgeWordDto>(total, _mapper.Map<IReadOnlyList<KnowledgeWordDto>>(items));
  763. }
  764. /// <summary>
  765. /// 获取知识库词库
  766. /// </summary>
  767. /// <param name="id"></param>
  768. /// <returns></returns>
  769. [HttpGet("knowledge_word/{id}")]
  770. public async Task<KnowledgeWord> WordEntity(string id)
  771. {
  772. return await _knowledgeWrodRepository.Queryable()
  773. .FirstAsync(x => x.Id == id);
  774. }
  775. /// <summary>
  776. /// 获取知识库词库基本信息
  777. /// </summary>
  778. /// <returns></returns>
  779. [HttpGet("knowledge_word/base")]
  780. public async Task<object> Base()
  781. {
  782. var rsp = new
  783. {
  784. KnowledgeWordClassify = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.KnowledgeWordClassify),
  785. };
  786. return rsp;
  787. }
  788. #endregion
  789. #region 知识纠错
  790. /// <summary>
  791. /// 新增知识纠错
  792. /// </summary>
  793. /// <param name="dtos"></param>
  794. /// <returns></returns>
  795. //[Permission(EPermission.AddKnowledgeCorrection)]
  796. [HttpPost("knowledge_correction")]
  797. [LogFilter("新增知识纠错")]
  798. public async Task Add([FromBody] KnowledgeCorrectionAddDto dto)
  799. {
  800. var correction = _mapper.Map<KnowledgeCorrection>(dto);
  801. await _knowledgeCorrectionRepository.AddAsync(correction, HttpContext.RequestAborted);
  802. }
  803. /// <summary>
  804. /// 删除知识纠错
  805. /// </summary>
  806. /// <param name="dto"></param>
  807. /// <returns></returns>
  808. //[Permission(EPermission.DeleteKnowledgeCorrection)]
  809. //[HttpDelete("knowledge_correction")]
  810. //public async Task Delete([FromBody] KnowledgeCorrectionDeleteDto dto)
  811. //{
  812. // await _knowledgeCorrectionRepository.RemoveAsync(x => x.Id == dto.Id);
  813. //}
  814. /// <summary>
  815. /// 更新知识纠错
  816. /// </summary>
  817. /// <param name="dto"></param>
  818. /// <returns></returns>
  819. //[Permission(EPermission.UpdateKnowledgeCorrection)]
  820. //[HttpPut("knowledge_correction")]
  821. //public async Task Update([FromBody] KnowledgeCorrectionUpdateDto dto)
  822. //{
  823. // var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  824. // if (correction is null)
  825. // throw UserFriendlyException.SameMessage("无效知识纠错");
  826. // _mapper.Map(dto, correction);
  827. // await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  828. //}
  829. /// <summary>
  830. /// 答复知识纠错
  831. /// </summary>
  832. /// <param name="dto"></param>
  833. /// <returns></returns>
  834. [Permission(EPermission.ReplyKnowledgeCorrection)]
  835. [HttpPut("knowledge_correction/Reply")]
  836. [LogFilter("答复知识纠错")]
  837. public async Task Reply([FromBody] KnowledgeCorrectionUpdateDto dto)
  838. {
  839. var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  840. if (correction is null)
  841. throw UserFriendlyException.SameMessage("无效知识纠错");
  842. _mapper.Map(dto, correction);
  843. correction.ReplyTime = DateTime.Now;
  844. correction.ReplyUserName = _sessionContext.UserName;
  845. correction.State = ECorrectionState.AlreadyAnswered;
  846. await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  847. }
  848. /// <summary>
  849. /// 获取知识纠错列表
  850. /// </summary>
  851. /// <param name="dto"></param>
  852. /// <returns></returns>
  853. [Permission(EPermission.KnowledgeCorrectionList)]
  854. [HttpGet("knowledge_correction/list")]
  855. public async Task<PagedDto<KnowledgeCorrectionDto>> List([FromQuery] KnowledgeCorrectionListDto dto)
  856. {
  857. var (total, items) = await _knowledgeCorrectionRepository.Queryable()
  858. .Includes(x => x.Knowledge)
  859. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  860. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  861. .Where(x=> !string.IsNullOrEmpty(x.Knowledge.Id))
  862. .OrderByDescending(x => x.CreationTime)
  863. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  864. return new PagedDto<KnowledgeCorrectionDto>(total, _mapper.Map<IReadOnlyList<KnowledgeCorrectionDto>>(items));
  865. }
  866. /// <summary>
  867. /// 获取知识库纠错
  868. /// </summary>
  869. /// <param name="id"></param>
  870. /// <returns></returns>
  871. //[Permission(EPermission.KnowledgeCorrectionEntity)]
  872. [HttpGet("knowledge_correction/{id}")]
  873. public async Task<KnowledgeCorrection> CorrectionEntity(string id)
  874. {
  875. return await _knowledgeCorrectionRepository.Queryable()
  876. .Includes(x => x.Knowledge)
  877. .FirstAsync(x => x.Id == id);
  878. }
  879. #endregion
  880. #region 知识提问
  881. /// <summary>
  882. /// 新增知识提问
  883. /// </summary>
  884. /// <param name="dtos"></param>
  885. /// <returns></returns>
  886. //[Permission(EPermission.AddKnowledgeQuestions)]
  887. [HttpPost("knowledge_questions")]
  888. [LogFilter("新增知识提问")]
  889. public async Task Add([FromBody] KnowledgeQuestionsAddDto dto)
  890. {
  891. var questions = _mapper.Map<KnowledgeQuestions>(dto);
  892. await _knowledgeQuestionsRepository.AddAsync(questions, HttpContext.RequestAborted);
  893. }
  894. /// <summary>
  895. /// 删除知识提问
  896. /// </summary>
  897. /// <param name="dto"></param>
  898. /// <returns></returns>
  899. //[Permission(EPermission.DeleteKnowledgeQuestions)]
  900. //[HttpDelete("knowledge_questions")]
  901. //public async Task Delete([FromBody] KnowledgeQuestionsDeleteDto dto)
  902. //{
  903. // await _knowledgeQuestionsRepository.RemoveAsync(x => x.Id == dto.Id);
  904. //}
  905. /// <summary>
  906. /// 更新知识提问
  907. /// </summary>
  908. /// <param name="dto"></param>
  909. /// <returns></returns>
  910. //[Permission(EPermission.UpdateKnowledgeQuestions)]
  911. //[HttpPut("knowledge_questions")]
  912. //public async Task Update([FromBody] KnowledgeQuestionsUpdateDto dto)
  913. //{
  914. // var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  915. // if (questions is null)
  916. // throw UserFriendlyException.SameMessage("无效知识提问");
  917. // _mapper.Map(dto, questions);
  918. // await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  919. //}
  920. /// <summary>
  921. /// 答复知识提问
  922. /// </summary>
  923. /// <param name="dto"></param>
  924. /// <returns></returns>
  925. [Permission(EPermission.ReplyKnowledgeQuestions)]
  926. [HttpPut("knowledge_questions/Reply")]
  927. [LogFilter("答复知识提问")]
  928. public async Task Reply([FromBody] KnowledgeQuestionsUpdateDto dto)
  929. {
  930. var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  931. if (questions is null)
  932. throw UserFriendlyException.SameMessage("无效知识提问");
  933. _mapper.Map(dto, questions);
  934. questions.ReplyTime = DateTime.Now;
  935. questions.ReplyUserName = _sessionContext.UserName;
  936. questions.State = ECorrectionState.AlreadyAnswered;
  937. await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  938. }
  939. /// <summary>
  940. /// 获取知识提问列表
  941. /// </summary>
  942. /// <param name="dto"></param>
  943. /// <returns></returns>
  944. [Permission(EPermission.KnowledgeQuestionsList)]
  945. [HttpGet("knowledge_questions/list")]
  946. public async Task<PagedDto<KnowledgeQuestionsDto>> List([FromQuery] KnowledgeQuestionsListDto dto)
  947. {
  948. var (total, items) = await _knowledgeQuestionsRepository.Queryable()
  949. .Includes(x => x.Knowledge)
  950. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  951. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  952. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  953. .OrderByDescending(x => x.CreationTime)
  954. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  955. return new PagedDto<KnowledgeQuestionsDto>(total, _mapper.Map<IReadOnlyList<KnowledgeQuestionsDto>>(items));
  956. }
  957. /// <summary>
  958. /// 获取知识提问
  959. /// </summary>
  960. /// <param name="id"></param>
  961. /// <returns></returns>
  962. //[Permission(EPermission.KnowledgeQuestionsEntity)]
  963. [HttpGet("knowledge_questions/{id}")]
  964. public async Task<KnowledgeQuestions> QuestionsEntity(string id)
  965. {
  966. return await _knowledgeQuestionsRepository.Queryable()
  967. .Includes(x => x.Knowledge)
  968. .FirstAsync(x => x.Id == id);
  969. }
  970. #endregion
  971. #region 知识收藏
  972. /// <summary>
  973. /// 知识收藏列表
  974. /// </summary>
  975. /// <param name="dto"></param>
  976. /// <returns></returns>
  977. [Permission(EPermission.KnowledgeCollectList)]
  978. [HttpGet("knowledge_collect/list")]
  979. public async Task<PagedDto<KnowledgeCollectDto>> List([FromQuery] KnowledgeCollectListDto dto)
  980. {
  981. var (total, items) = await _knowledgeCollectRepository.Queryable()
  982. .Includes(x=>x.Knowledge)
  983. .WhereIF(!string.IsNullOrEmpty(dto.Keyword),x=>x.Knowledge.Title.Contains(dto.Keyword!)||( x.Knowledge.Summary != null && x.Knowledge.Summary.Contains(dto.Keyword!)))
  984. .Where(x=>x.CreatorId == _sessionContext.UserId)
  985. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  986. .OrderByDescending(x => x.CreationTime)
  987. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  988. return new PagedDto<KnowledgeCollectDto>(total,_mapper.Map<IReadOnlyList<KnowledgeCollectDto>>(items));
  989. }
  990. /// <summary>
  991. /// 新增知识收藏
  992. /// </summary>
  993. /// <param name="dtos"></param>
  994. /// <returns></returns>
  995. //[Permission(EPermission.AddKnowledgeCollect)]
  996. [HttpPost("knowledge_collect")]
  997. [LogFilter("知识收藏")]
  998. public async Task Add([FromBody] KnowledgeCollectAddDto dto)
  999. {
  1000. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1001. if (collect != null)
  1002. {
  1003. collect.Collect = dto.Collect;
  1004. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1005. }
  1006. else
  1007. {
  1008. var collectNew = _mapper.Map<KnowledgeCollect>(dto);
  1009. await _knowledgeCollectRepository.AddAsync(collectNew, HttpContext.RequestAborted);
  1010. }
  1011. }
  1012. /// <summary>
  1013. /// 知识评分
  1014. /// </summary>
  1015. /// <param name="dto"></param>
  1016. /// <returns></returns>
  1017. //[Permission(EPermission.AddKnowledgeScore)]
  1018. [HttpDelete("knowledge_score")]
  1019. [LogFilter("知识评分")]
  1020. public async Task Delete([FromBody] KnowledgeCollectAddDto dto)
  1021. {
  1022. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1023. if (collect != null)
  1024. {
  1025. if (collect.Score > 0)
  1026. throw UserFriendlyException.SameMessage("当前知识已经评分");
  1027. collect.Score = dto.Score;
  1028. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1029. }
  1030. else
  1031. {
  1032. var questions = _mapper.Map<KnowledgeCollect>(dto);
  1033. await _knowledgeCollectRepository.AddAsync(questions, HttpContext.RequestAborted);
  1034. }
  1035. //计算总分
  1036. var sugar = _knowledgeCollectRepository.Queryable().Where(x => x.KnowledgeId == dto.KnowledgeId);
  1037. var count = await sugar.CountAsync();
  1038. var collects = await sugar.SumAsync(x => x.Score);
  1039. var score = collects / count;
  1040. var knowledge = await _knowledgeRepository.GetAsync(x => x.Id == dto.KnowledgeId);
  1041. if (knowledge != null)
  1042. {
  1043. knowledge.Score = decimal.Round(score.Value, 1);
  1044. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  1045. }
  1046. }
  1047. #endregion
  1048. #region 知识评论
  1049. /// <summary>
  1050. /// 新增知识评论
  1051. /// </summary>
  1052. /// <param name="dto"></param>
  1053. /// <returns></returns>
  1054. [HttpPost("knowledge_comment")]
  1055. public async Task Add([FromBody] KnowledgeCommentAddDto dto)
  1056. {
  1057. var model = _mapper.Map<KnowledgeComment>(dto);
  1058. await _knowledgeCommentRepository.AddAsync(model, HttpContext.RequestAborted);
  1059. if (!string.IsNullOrEmpty(dto.ReplyId))
  1060. {
  1061. var comment = await _knowledgeCommentRepository.GetAsync(dto.ReplyId);
  1062. if (comment != null)
  1063. {
  1064. comment.ReplyNum++;
  1065. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1066. }
  1067. }
  1068. }
  1069. /// <summary>
  1070. /// 删除知识评论
  1071. /// </summary>
  1072. /// <param name="dto"></param>
  1073. /// <returns></returns>
  1074. [HttpDelete("knowledge_comment")]
  1075. public async Task Delete([FromBody] KnowledgeCommentDeleteDto dto)
  1076. {
  1077. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1078. if (comment is null)
  1079. throw UserFriendlyException.SameMessage("无效评论");
  1080. if (comment.CreatorId != _sessionContext.UserId)
  1081. throw UserFriendlyException.SameMessage("只有评论者可以删除当前评论");
  1082. await _knowledgeCommentRepository.RemoveAsync(x => x.Id == dto.Id);
  1083. }
  1084. /// <summary>
  1085. /// 修改知识评论
  1086. /// </summary>
  1087. /// <param name="dto"></param>
  1088. /// <returns></returns>
  1089. [HttpPut("knowledge_comment")]
  1090. public async Task Update([FromBody] KnowledgeCommentUpdateDto dto)
  1091. {
  1092. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1093. if (comment is null)
  1094. throw UserFriendlyException.SameMessage("无效评论");
  1095. _mapper.Map(dto, comment);
  1096. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1097. }
  1098. /// <summary>
  1099. /// 知识评论列表
  1100. /// </summary>
  1101. /// <param name="dto"></param>
  1102. /// <returns></returns>
  1103. [HttpGet("knowledge_comment/list")]
  1104. public async Task<List<KnowledgeCommentDto>> List([FromQuery] KnowledgeCommentListDto dto)
  1105. {
  1106. var comments = await _knowledgeCommentRepository.Queryable()
  1107. .WhereIF(!string.IsNullOrEmpty(dto.KnowledgeId), x => x.KnowledgeId == dto.KnowledgeId)
  1108. .WhereIF(!string.IsNullOrEmpty(dto.ReplyId), x => x.ReplyId == dto.ReplyId)
  1109. .WhereIF(dto.All.HasValue && dto.All == false, x => x.CreatorId == _sessionContext.UserId)
  1110. .OrderByDescending(x => x.CreationTime)
  1111. .ToListAsync();
  1112. return new List<KnowledgeCommentDto>(_mapper.Map<IReadOnlyList<KnowledgeCommentDto>>(comments));
  1113. }
  1114. #endregion
  1115. }
  1116. }