KnowledgeController.cs 30 KB

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