KnowledgeController.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. using Hotline.Application.FlowEngine;
  2. using Hotline.Application.Knowledge;
  3. using Hotline.FlowEngine.Definitions;
  4. using Hotline.FlowEngine.Workflows;
  5. using Hotline.KnowledgeBase;
  6. using Hotline.KnowledgeBase.Notifies;
  7. using Hotline.Permissions;
  8. using Hotline.Repository.SqlSugar.Extensions;
  9. using Hotline.Settings;
  10. using Hotline.Settings.Hotspots;
  11. using Hotline.Share.Dtos;
  12. using Hotline.Share.Dtos.FlowEngine;
  13. using Hotline.Share.Dtos.Knowledge;
  14. using Hotline.Share.Enums.KnowledgeBase;
  15. using Hotline.Users;
  16. using MapsterMapper;
  17. using MediatR;
  18. using Microsoft.AspNetCore.Mvc;
  19. using SqlSugar;
  20. using XF.Domain.Authentications;
  21. using XF.Domain.Exceptions;
  22. namespace Hotline.Api.Controllers
  23. {
  24. /// <summary>
  25. ///
  26. /// </summary>
  27. public class KnowledgeController : BaseController
  28. {
  29. #region 注入
  30. private readonly IKnowledgeRepository _knowledgeRepository;
  31. private readonly IKnowledgeTempRepository _knowledgeTempRepository;
  32. private readonly ISessionContext _sessionContext;
  33. private readonly IKnowledgeDomainService _knowledgeDomainService;
  34. private readonly IMapper _mapper;
  35. private readonly IKnowApplication _knowApplication;
  36. private readonly IMediator _mediator;
  37. private readonly IWorkflowApplication _workflowApplication;
  38. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  39. private readonly IWorkflowDomainService _workflowDomainService;
  40. private readonly IDefinitionDomainService _definitionDomainService;
  41. private readonly IUserRepository _userRepository;
  42. private readonly IKnowledgeTypeRepository _knowledgeTypeRepository;
  43. private readonly IHotspotTypeRepository _hotspotTypeRepository;
  44. /// <summary>
  45. ///
  46. /// </summary>
  47. /// <param name="knowledgeRepository"></param>
  48. /// <param name="knowledgeTempRepository"></param>
  49. /// <param name="sessionContext"></param>
  50. /// <param name="knowledgeDomainService"></param>
  51. /// <param name="mapper"></param>
  52. /// <param name="knowApplication"></param>
  53. /// <param name="mediator"></param>
  54. /// <param name="workflowApplication"></param>
  55. /// <param name="knowledgeWorkFlowRepository"></param>
  56. /// <param name="workflowDomainService"></param>
  57. /// <param name="definitionDomainService"></param>
  58. /// <param name="userRepository"></param>
  59. /// <param name="knowledgeTypeRepository"></param>
  60. /// <param name="hotspotTypeRepository"></param>
  61. public KnowledgeController(IKnowledgeRepository knowledgeRepository, IKnowledgeTempRepository knowledgeTempRepository,
  62. ISessionContext sessionContext, IKnowledgeDomainService knowledgeDomainService, IMapper mapper, IKnowApplication knowApplication,
  63. IMediator mediator, IWorkflowApplication workflowApplication, IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository, IWorkflowDomainService workflowDomainService
  64. , IDefinitionDomainService definitionDomainService, IUserRepository userRepository, IKnowledgeTypeRepository knowledgeTypeRepository, IHotspotTypeRepository hotspotTypeRepository)
  65. {
  66. _knowledgeRepository = knowledgeRepository;
  67. _knowledgeTempRepository = knowledgeTempRepository;
  68. _sessionContext = sessionContext;
  69. _knowledgeDomainService = knowledgeDomainService;
  70. _mapper = mapper;
  71. _knowApplication = knowApplication;
  72. _mediator = mediator;
  73. _workflowApplication = workflowApplication;
  74. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  75. _workflowDomainService = workflowDomainService;
  76. _definitionDomainService = definitionDomainService;
  77. _userRepository = userRepository;
  78. _knowledgeTypeRepository = knowledgeTypeRepository;
  79. _hotspotTypeRepository = hotspotTypeRepository;
  80. }
  81. #endregion
  82. #region 草稿箱
  83. /// <summary>
  84. /// 草稿箱-新增
  85. /// </summary>
  86. /// <param name="dto"></param>
  87. /// <returns></returns>
  88. [Permission(EPermission.KnowledgeDraftsAdd)]
  89. [HttpPost("adddrafts")]
  90. public async Task<string> AddKnowledgeDrafts([FromBody] AddKnowledgeDto dto)
  91. {
  92. var kn = _mapper.Map<KnowledgeTemp>(dto);
  93. if (string.IsNullOrEmpty(dto.Code))
  94. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  95. return await _knowledgeTempRepository.AddAsync(kn, HttpContext.RequestAborted);
  96. }
  97. /// <summary>
  98. /// 草稿箱-修改
  99. /// </summary>
  100. /// <param name="dto"></param>
  101. /// <returns></returns>
  102. [Permission(EPermission.KnowledgeDraftsUpdate)]
  103. [HttpPut("updatedrafts")]
  104. public async Task UpdateKnowledgeDrafts([FromBody] UpdateKnowledgeDto dto)
  105. {
  106. var kn = _mapper.Map<KnowledgeTemp>(dto);
  107. await _knowledgeTempRepository.UpdateAsync(kn, HttpContext.RequestAborted);
  108. }
  109. /// <summary>
  110. /// 草稿箱-查询详情
  111. /// </summary>
  112. /// <param name="Id"></param>
  113. /// <returns></returns>
  114. [HttpGet("draftsinfo/{Id}")]
  115. public async Task<KnowledgeInfoDto> KnowledgeDraftsInfo(string Id)
  116. {
  117. var temp = await _knowledgeTempRepository.GetAsync(Id, HttpContext.RequestAborted);
  118. if (temp is null)
  119. throw UserFriendlyException.SameMessage("知识草稿查询失败!");
  120. var knowledgeInfoDto = _mapper.Map<KnowledgeInfoDto>(temp);
  121. //分类
  122. var type = await _knowledgeTypeRepository.GetAsync(temp.KnowledgeTypeId, HttpContext.RequestAborted);
  123. if (type != null)
  124. knowledgeInfoDto.KnowledgeTypeName = type.SpliceName;
  125. //热点
  126. var hot = await _hotspotTypeRepository.GetAsync(temp.HotspotId, HttpContext.RequestAborted);
  127. if (hot != null)
  128. knowledgeInfoDto.HotspotName = hot.HotSpotFullName;
  129. return knowledgeInfoDto;
  130. }
  131. /// <summary>
  132. /// 草稿箱删除
  133. /// </summary>
  134. /// <param name="Id"></param>
  135. /// <returns></returns>
  136. [Permission(EPermission.KnowledgeDraftsDelete)]
  137. [HttpDelete("removedrafts")]
  138. public async Task RemoveKnowledgeDrafts(string Id)
  139. {
  140. if (string.IsNullOrEmpty(Id))
  141. throw UserFriendlyException.SameMessage("Id不能为空!");
  142. await _knowledgeTempRepository.RemoveAsync(p => p.Id == Id, false, HttpContext.RequestAborted);
  143. }
  144. /// <summary>
  145. /// 我的草稿箱
  146. /// </summary>
  147. /// <param name="pagedDto"></param>
  148. /// <returns></returns>
  149. [Permission(EPermission.KnowledgeMyDraftsList)]
  150. [HttpGet("mydraftslist")]
  151. public async Task<PagedDto<KnowledgeDataDto>> MyDraftsList([FromQuery] MyDraftsListPagedDto pagedDto)
  152. {
  153. var (total, items) = await _knowledgeTempRepository
  154. .Queryable()
  155. .Includes(it => it.User)
  156. .Includes(it => it.KnowledgeType)
  157. .Where(p => p.CreatorId == _sessionContext.RequiredUserId)
  158. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  159. .WhereIF(!string.IsNullOrEmpty(pagedDto.KnowledgeTypeId), d => d.KnowledgeTypeId == pagedDto.KnowledgeTypeId)
  160. .WhereIF(pagedDto.StartTime != null, d => d.CreationTime >= pagedDto.StartTime)
  161. .WhereIF(pagedDto.EndTime != null, d => d.CreationTime <= pagedDto.EndTime)
  162. .OrderByDescending(p => p.CreationTime)
  163. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  164. return new PagedDto<KnowledgeDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(items));
  165. }
  166. #endregion
  167. #region 知识管理
  168. /// <summary>
  169. /// 知识库-知识修改-查询详情
  170. /// </summary>
  171. /// <param name="Id"></param>
  172. /// <returns></returns>
  173. [HttpGet("updateinfo/{Id}")]
  174. public async Task<KnowledgeInfoDto> KnowledgeUpdateInfo(string Id)
  175. {
  176. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  177. if (know is null)
  178. throw UserFriendlyException.SameMessage("知识查询失败!");
  179. var knowledgeInfoDto = _mapper.Map<KnowledgeInfoDto>(know);
  180. //分类
  181. var type = await _knowledgeTypeRepository.GetAsync(know.KnowledgeTypeId, HttpContext.RequestAborted);
  182. if (type != null)
  183. knowledgeInfoDto.KnowledgeTypeName = type.SpliceName;
  184. //热点
  185. var hot = await _hotspotTypeRepository.GetAsync(know.HotspotId, HttpContext.RequestAborted);
  186. if (hot != null)
  187. knowledgeInfoDto.HotspotName = hot.HotSpotFullName;
  188. return knowledgeInfoDto;
  189. }
  190. /// <summary>
  191. /// 知识库-查询详情-增加浏览量
  192. /// </summary>
  193. /// <param name="Id">知识Id</param>
  194. /// <param name="IsAddPv">默认不增加,如果为空不增加,不为空增加浏览量</param>
  195. /// <returns></returns>
  196. [HttpGet("info/{Id}")]
  197. public async Task<KnowledgeShowInfoDto> KnowledgeInfo(string Id, string? IsAddPv = "")
  198. {
  199. var knowledge = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
  200. if (knowledge is null)
  201. throw UserFriendlyException.SameMessage("知识查询失败!");
  202. //转化
  203. var knowledgeShowInfoDto = _mapper.Map<KnowledgeShowInfoDto>(knowledge);
  204. //查询其他
  205. var user = await _userRepository.GetAsync(knowledge.CreatorId, HttpContext.RequestAborted);
  206. if (user != null)
  207. knowledgeShowInfoDto.CreatorName = user.Name;
  208. var type = await _knowledgeTypeRepository.GetAsync(knowledge.KnowledgeTypeId, HttpContext.RequestAborted);
  209. if (type != null)
  210. knowledgeShowInfoDto.KnowledgeTypeName = type.SpliceName;
  211. var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
  212. if (hot != null)
  213. knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
  214. if (!string.IsNullOrEmpty(IsAddPv))
  215. _mediator.Publish(new GetKnowledgeInfoNotify(knowledge));
  216. return knowledgeShowInfoDto;
  217. }
  218. /// <summary>
  219. /// 知识库-新增
  220. /// </summary>
  221. /// <param name="dto"></param>
  222. /// <returns></returns>
  223. [Permission(EPermission.AddKnowledge)]
  224. [HttpPost("add")]
  225. public async Task<string> AddKnowledge([FromBody] AddKnowledgeDto dto)
  226. {
  227. //知识处理逻辑
  228. return await _knowledgeDomainService.KnowledgeAdd(dto, HttpContext.RequestAborted);
  229. }
  230. ///// <summary>
  231. ///// 知识库-修改
  232. ///// </summary>
  233. ///// <param name="dto"></param>
  234. ///// <returns></returns>
  235. //[Permission(EPermission.KnowledgeUpdate)]
  236. //[HttpPut("update")]
  237. //public async Task<string> UpdateKnowledge([FromBody] UpdateKnowledgeDto dto)
  238. //{
  239. // //知识更新流程业务
  240. // return await _knowledgeDomainService.KnowledgeUpdate(dto, HttpContext.RequestAborted);
  241. //}
  242. /// <summary>
  243. /// 知识库-知识下架
  244. /// </summary>
  245. /// <param name="Id"></param>
  246. /// <returns></returns>
  247. [Permission(EPermission.KnowledgeOffShelf)]
  248. [HttpPut("offshelf")]
  249. public async Task KnowledgeOffShelf(string Id)
  250. {
  251. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  252. if (know != null && know.Status == EKnowledgeStatus.OnShelf)
  253. {
  254. know.Status = EKnowledgeStatus.OffShelf;
  255. know.OnShelfTime = null;
  256. know.OffShelfTime = DateTime.Now;
  257. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  258. }
  259. else
  260. throw UserFriendlyException.SameMessage("知识下架失败");
  261. }
  262. /// <summary>
  263. /// 知识库-知识上架
  264. /// </summary>
  265. /// <param name="Id"></param>
  266. /// <returns></returns>
  267. [Permission(EPermission.KnowledgeOnTheShelf)]
  268. [HttpPut("ontheshelf")]
  269. public async Task KnowledgeOnTheShelf(string Id)
  270. {
  271. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  272. if (know != null && know.Status == EKnowledgeStatus.OffShelf)
  273. {
  274. know.Status = EKnowledgeStatus.OnShelf;
  275. know.OnShelfTime = DateTime.Now;
  276. know.OffShelfTime = null;
  277. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  278. }
  279. else
  280. throw UserFriendlyException.SameMessage("知识上架失败");
  281. }
  282. /// <summary>
  283. /// 撤销
  284. /// </summary>
  285. /// <param name="workFlowId"></param>
  286. /// <returns></returns>
  287. [HttpPut("revoke")]
  288. public async Task KnowledgeRevoke(string workFlowId)
  289. {
  290. await _knowledgeDomainService.KnowledgeRevoke(workFlowId, HttpContext.RequestAborted);
  291. }
  292. /// <summary>
  293. /// 根据workFlowId,查询审批明细
  294. /// </summary>
  295. /// <param name="workFlowId"></param>
  296. /// <returns></returns>
  297. [HttpGet("getworkflow")]
  298. public async Task<Workflow> GetWorkflow(string workFlowId)
  299. {
  300. return await _workflowDomainService.GetWorkflowAsync(workFlowId, withSteps: true, withSupplements: true, withAssigns: true, cancellationToken: HttpContext.RequestAborted);
  301. }
  302. /// <summary>
  303. /// 知识申请-关联知识-获取知识列表
  304. /// </summary>
  305. /// <returns></returns>
  306. [HttpGet("getknowledge")]
  307. public async Task<IReadOnlyList<KnowledgeCreateBMDataDto>> GetKnowledge()
  308. {
  309. var temp = await _knowledgeRepository
  310. .Queryable()
  311. .LeftJoin<SystemOrganize>((o, sys) => o.CreatorOrgId == sys.Id)
  312. .Where((o, sys) => o.IsDeleted == false)
  313. //重新构建数据
  314. .Select((o, sys) => new
  315. {
  316. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  317. DepartmentId = sys.Id,
  318. Department = sys.OrgName,
  319. o.Id,
  320. o.Title,
  321. o.Status,
  322. o.Code
  323. })
  324. //将结果合并成一个表
  325. .MergeTable()
  326. //取第一条数据
  327. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  328. .ToListAsync();
  329. //返回数据
  330. return _mapper.Map<IReadOnlyList<KnowledgeCreateBMDataDto>>(temp);
  331. }
  332. #endregion
  333. #region 知识列表
  334. /// <summary>
  335. /// 知识查询
  336. /// </summary>
  337. /// <param name="pagedDto"></param>
  338. /// <returns></returns>
  339. [Permission(EPermission.KnowledgeAllList)]
  340. [HttpGet()]
  341. public async Task<PagedDto<KnowledgeDataDto>> GetKnowList([FromQuery] KnowPagedListDto pagedDto)
  342. {
  343. return await _knowApplication.GetKnowList(pagedDto);
  344. }
  345. #endregion
  346. #region 知识检索
  347. /// <summary>
  348. /// 知识检索
  349. /// </summary>
  350. /// <param name="pagedDto"></param>
  351. /// <returns></returns>
  352. [Permission(EPermission.KnowledgeRetrieval)]
  353. [HttpGet("knowretrieval")]
  354. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrieval([FromQuery] KnowledgeRetrievalPagedListDto pagedDto)
  355. {
  356. //if (string.IsNullOrEmpty(pagedDto.Keyword))
  357. // throw UserFriendlyException.SameMessage("请输入关键字");
  358. RefAsync<int> total = 0;
  359. var Keyword = pagedDto.Keyword?.Trim();
  360. var temp = await _knowledgeRepository
  361. .Queryable()
  362. .Where(p => p.IsDeleted == false)
  363. .Select(o => new
  364. {
  365. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  366. o.Id,
  367. o.Code,
  368. o.Title,
  369. o.Summary,
  370. o.Content,
  371. o.PageView,
  372. o.Additions,
  373. o.Status
  374. })
  375. //将结果合并成一个表
  376. .MergeTable()
  377. //取第一条数据
  378. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  379. .WhereIF((pagedDto.RetrievalType == null || pagedDto.RetrievalType == EKnowledgeRetrievalType.All) && !string.IsNullOrEmpty(Keyword), d => d.Title.Contains(Keyword) || d.Content.Contains(Keyword))// || d.Additions.Contains(pagedDto.Keyword)
  380. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Title && !string.IsNullOrEmpty(Keyword), d => d.Title.Contains(Keyword))
  381. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Content && !string.IsNullOrEmpty(Keyword), d => d.Content.Contains(Keyword))
  382. // .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Enclosure, d => d.Additions.Contains(pagedDto.Keyword))
  383. .OrderByDescending(p => p.PageView)
  384. .ToPageListAsync(pagedDto.PageIndex, pagedDto.PageSize, total);
  385. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  386. }
  387. #endregion
  388. #region 我的知识删除列表
  389. /// <summary>
  390. /// 我的知识删除列表
  391. /// </summary>
  392. /// <param name="pagedDto"></param>
  393. /// <returns></returns>
  394. [HttpGet("deletelist")]
  395. [Permission(EPermission.KnowledgeDeleteApply)]
  396. public async Task<PagedDto<KnowledgeDeleteApplyDataDto>> GetDeleteApplyList([FromQuery] KnowledgeDeletelPagedListDto pagedDto)
  397. {
  398. var (total, items) = await _knowledgeWorkFlowRepository
  399. .Queryable(includeDeleted: true)
  400. .Includes(it => it.Knowledge)
  401. .Includes(it => it.User)
  402. .Includes(it => it.SystemOrganize)
  403. .Includes(it => it.Knowledge, it => it.KnowledgeType)
  404. .Includes(it => it.Knowledge, it => it.HotspotType)
  405. .Includes(it => it.Workflow)
  406. .Where(d => d.CreatorId == _sessionContext.RequiredUserId && d.WorkflowModuleStatus == EKnowledgeApplyType.Delete)
  407. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  408. .WhereIF(pagedDto.StartApplyTime.HasValue, d => d.CreationTime >= pagedDto.StartApplyTime)
  409. .WhereIF(pagedDto.EndApplyTime.HasValue, d => d.CreationTime <= pagedDto.EndApplyTime)
  410. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  411. || d.Knowledge.SystemOrganize.OrgName.Contains(pagedDto.Keyword!)
  412. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  413. .OrderByDescending(p => p.CreationTime)
  414. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  415. return new PagedDto<KnowledgeDeleteApplyDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDeleteApplyDataDto>>(items));
  416. }
  417. #endregion
  418. #region 审核管理
  419. /// <summary>
  420. /// 审核管理
  421. /// </summary>
  422. /// <param name="pagedDto"></param>
  423. /// <returns></returns>
  424. [Permission(EPermission.KnowledgeApprovedAllList)]
  425. [HttpGet("approvedlist")]
  426. public async Task<PagedDto<KnowledgeApprovalDataDto>> ApprovedList([FromQuery] KnowledgeApprovalPagedListDto pagedDto)
  427. {
  428. var (total, items) = await _knowledgeWorkFlowRepository
  429. .Queryable(includeDeleted: true)
  430. .Includes(it => it.Knowledge)
  431. .Includes(it => it.User)
  432. .Includes(it => it.SystemOrganize)
  433. .Includes(it => it.Knowledge, it => it.KnowledgeType)
  434. .Includes(it => it.Workflow)
  435. .WhereIF(pagedDto.EKnowledgeApplyType.HasValue, d => d.WorkflowModuleStatus == pagedDto.EKnowledgeApplyType)
  436. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  437. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  438. || d.Knowledge.SystemOrganize.OrgName.Contains(pagedDto.Keyword!)
  439. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  440. .OrderByDescending(p => p.CreationTime)
  441. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  442. //处理是否可以办理
  443. items.ForEach(d => d.CanHandle = d.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgCode));
  444. return new PagedDto<KnowledgeApprovalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApprovalDataDto>>(items));
  445. }
  446. #endregion
  447. #region 工单受理,知识库检索
  448. /// <summary>
  449. /// 获取知识热点词
  450. /// </summary>
  451. /// <returns></returns>
  452. [HttpGet("getkeyword")]
  453. public async Task<List<string>> GetKeyWord()
  454. {
  455. return await _knowledgeDomainService.GetKeyWord();
  456. }
  457. /// <summary>
  458. /// 工单受理知识检索
  459. /// </summary>
  460. /// <param name="pagedDto"></param>
  461. /// <returns></returns>
  462. [HttpGet("knowpopscreen")]
  463. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowPopScreen([FromQuery] KnowledgePopScreenPagedListDto pagedDto)
  464. {
  465. //if (string.IsNullOrEmpty(pagedDto.Keyword)&& string.IsNullOrEmpty(pagedDto.HotspotId))
  466. // throw UserFriendlyException.SameMessage("请选择热点或输入关键字");
  467. RefAsync<int> total = 0;
  468. var temp = await _knowledgeRepository
  469. .Queryable()
  470. .Where(p => p.IsDeleted == false)
  471. .Select(o => new
  472. {
  473. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  474. o.Id,
  475. o.Code,
  476. o.Title,
  477. o.Summary,
  478. o.Content,
  479. o.PageView,
  480. o.Keywords,
  481. o.HotspotId,
  482. o.Status
  483. })
  484. //将结果合并成一个表
  485. .MergeTable()
  486. //取第一条数据
  487. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  488. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), p => p.Title.Contains(pagedDto.Keyword) || p.Keywords.Contains(pagedDto.Keyword))
  489. .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotId), p => p.HotspotId == pagedDto.HotspotId)
  490. .OrderByDescending(p => p.PageView)
  491. .ToPageListAsync(pagedDto.PageIndex, pagedDto.PageSize, total);
  492. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  493. }
  494. #endregion
  495. #region 流程相关
  496. /// <summary>
  497. /// 新增-开始流程
  498. /// </summary>
  499. /// <param name="id">知识id</param>
  500. /// <param name="dto">流程开启参数</param>
  501. /// <returns></returns>
  502. [HttpPost("{id}/add-startflow")]
  503. public async Task AddStartFlow(string id, [FromBody] StartWorkflowDto dto)
  504. {
  505. await StartFlow(id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, dto);
  506. }
  507. ///// <summary>
  508. ///// 修改-开始流程
  509. ///// </summary>
  510. ///// <param name="id">知识id</param>
  511. ///// <param name="dto">流程开启参数</param>
  512. ///// <returns></returns>
  513. //[HttpPost("{id}/update-startflow")]
  514. //public async Task UpdateStartFlow(string id, [FromBody] StartWorkflowDto dto)
  515. //{
  516. // await StartFlow(id, WorkflowModuleConsts.KnowledgeUpdate, EKnowledgeApplyType.Update, dto);
  517. //}
  518. /// <summary>
  519. /// 删除-开始流程
  520. /// </summary>
  521. /// <param name="id">知识id</param>
  522. /// <param name="dto">流程开启参数</param>
  523. /// <returns></returns>
  524. [HttpPost("{id}/remove-startflow")]
  525. public async Task RemoveStartFlow(string id, [FromBody] StartWorkflowDto dto)
  526. {
  527. await StartFlow(id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, dto);
  528. }
  529. /// <summary>
  530. /// 查询知识库办理流程开启参数-新增
  531. /// </summary>
  532. /// <returns></returns>
  533. [HttpGet("add-flow-start")]
  534. public async Task<IReadOnlyList<NextStepOptions>> GetAddFlowStartOptionsAsync()
  535. {
  536. return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.KnowledgeAdd, HttpContext.RequestAborted);
  537. }
  538. ///// <summary>
  539. ///// 查询知识库办理流程开启参数-修改
  540. ///// </summary>
  541. ///// <returns></returns>
  542. //[HttpGet("update-flow-start")]
  543. //public async Task<IReadOnlyList<NextStepOptions>> GetUpdateFlowStartOptionsAsync()
  544. //{
  545. // return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.KnowledgeUpdate, HttpContext.RequestAborted);
  546. //}
  547. /// <summary>
  548. /// 查询知识库办理流程开启参数-删除
  549. /// </summary>
  550. /// <returns></returns>
  551. [HttpGet("remove-flow-start")]
  552. public async Task<IReadOnlyList<NextStepOptions>> GetRemoveFlowStartOptionsAsync()
  553. {
  554. return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.KnowledgeDelete, HttpContext.RequestAborted);
  555. }
  556. #endregion
  557. #region 私有方法-开始流程
  558. /// <summary>
  559. /// 开始流程
  560. /// </summary>
  561. /// <param name="id">知识ID</param>
  562. /// <param name="moduleCode">知识模板编号</param>
  563. /// <param name="eKnowledgeApplyType">申请类型</param>
  564. /// <param name="dto">流程开启参数</param>
  565. /// <returns></returns>
  566. private async Task StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
  567. {
  568. var knowledge = await _knowledgeRepository.GetAsync(id, HttpContext.RequestAborted);
  569. if (knowledge == null)
  570. throw UserFriendlyException.SameMessage("无效知识编号");
  571. if (eKnowledgeApplyType == EKnowledgeApplyType.Delete)
  572. {
  573. if (knowledge.IsDeleted == true)
  574. throw UserFriendlyException.SameMessage("知识删除失败");
  575. //验证是否已经发起过知识删除流程
  576. var exists = await _knowledgeWorkFlowRepository.GetAsync(p => p.KnowledgeId == knowledge.Id && p.WorkflowModuleStatus == EKnowledgeApplyType.Delete
  577. && (p.WorkFlowApplyStatus == EKnowledgeWorkFlowStatus.Success || p.WorkFlowApplyStatus == EKnowledgeWorkFlowStatus.Auditing));
  578. if (exists != null)
  579. throw UserFriendlyException.SameMessage($"该知识已发起过{WorkflowModule.Modules[WorkflowModuleConsts.KnowledgeDelete]}流程");
  580. }
  581. if (!string.IsNullOrEmpty(knowledge.WorkflowId) && eKnowledgeApplyType != EKnowledgeApplyType.Delete)
  582. throw UserFriendlyException.SameMessage("知识已发起流程");
  583. var definition = await _definitionDomainService.GetLastEnableByModuleCodeAsync(
  584. moduleCode, HttpContext.RequestAborted);
  585. if (definition is null)
  586. throw UserFriendlyException.SameMessage("未配置流程模板");
  587. //知识审批主表
  588. var flowId = await _knowledgeDomainService.AddWorkFlowAsync(id, eKnowledgeApplyType, HttpContext.RequestAborted);
  589. dto.DefinitionCode = definition.Code;
  590. dto.Title = knowledge.Title;
  591. await _workflowApplication.StartWorkflowAsync(dto, flowId, HttpContext.RequestAborted);
  592. //if (eKnowledgeApplyType != EKnowledgeApplyType.Delete)
  593. // //修改流程ID
  594. // await _knowledgeDomainService.UpdateWorkFlowId(id, workflowId, HttpContext.RequestAborted);
  595. }
  596. #endregion
  597. }
  598. }