KnowledgeDomainService.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. using DotNetCore.CAP;
  2. using Hotline.FlowEngine;
  3. using Hotline.FlowEngine.WorkflowModules;
  4. using Hotline.FlowEngine.Workflows;
  5. using Hotline.Share.Dtos.Knowledge;
  6. using Hotline.Share.Enums.KnowledgeBase;
  7. using Hotline.Share.Mq;
  8. using MapsterMapper;
  9. using SqlSugar;
  10. using XF.Domain.Dependency;
  11. using XF.Domain.Exceptions;
  12. using XF.Domain.Repository;
  13. namespace Hotline.KnowledgeBase
  14. {
  15. public class KnowledgeDomainService : IKnowledgeDomainService, IScopeDependency
  16. {
  17. private readonly IKnowledgeRepository _knowledgeRepository;
  18. private readonly IMapper _mapper;
  19. private readonly IRepository<KnowledgePv> _knowledgePVRepository;
  20. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  21. private readonly ICapPublisher _capPublisher;
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. /// <param name="knowledgeRepository"></param>
  26. /// <param name="mapper"></param>
  27. /// <param name="knowledgePVRepository"></param>
  28. /// <param name="knowledgeWorkFlowRepository"></param>
  29. /// <param name="capPublisher"></param>
  30. public KnowledgeDomainService(IKnowledgeRepository knowledgeRepository, IMapper mapper, IRepository<KnowledgePv> knowledgePVRepository
  31. , IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository, ICapPublisher capPublisher)
  32. {
  33. _knowledgeRepository = knowledgeRepository;
  34. _mapper = mapper;
  35. _knowledgePVRepository = knowledgePVRepository;
  36. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  37. _capPublisher = capPublisher;
  38. }
  39. /// <summary>
  40. /// 知识库-查询详情-增加浏览量
  41. /// </summary>
  42. /// <param name="Id"></param>
  43. /// <returns></returns>
  44. public async Task<Knowledge> KnowledgeInfo(string Id, CancellationToken cancellationToken)
  45. {
  46. var know = await _knowledgeRepository.Queryable(includeDeleted: true).Includes(x=>x.Workflow).FirstAsync(p => p.Id == Id);
  47. if (know is null)
  48. throw UserFriendlyException.SameMessage("知识查询失败!");
  49. return know;
  50. }
  51. /// <summary>
  52. /// 浏览记录写入
  53. /// </summary>
  54. /// <param name="know"></param>
  55. /// <param name="cancellationToken"></param>
  56. /// <returns></returns>
  57. public async Task KnowledgePvIncreaseAsync(Knowledge know, CancellationToken cancellationToken)
  58. {
  59. //写入浏览记录
  60. KnowledgePv knowledgePv = new()
  61. {
  62. CreationTime = DateTime.Now,
  63. KnowledgeCode = know.Code
  64. };
  65. //浏览记录写入
  66. await _knowledgePVRepository.AddAsync(knowledgePv, cancellationToken);
  67. //修改浏览量
  68. know.PageView++;
  69. //修改点击量
  70. await _knowledgeRepository.UpdateAsync(know, cancellationToken);
  71. }
  72. /// <summary>
  73. /// 知识审批主表
  74. /// </summary>
  75. /// <param name="knowId">知识Id</param>
  76. /// <param name="eKnowledgeApplyType">申请类型</param>
  77. /// <param name="cancellationToken"></param>
  78. /// <returns></returns>
  79. public async Task<string> AddWorkFlowAsync(string knowId, EKnowledgeApplyType eKnowledgeApplyType, CancellationToken cancellationToken)
  80. {
  81. KnowledgeWorkFlow workFlow = new()
  82. {
  83. KnowledgeId = knowId,
  84. WorkflowModuleStatus = eKnowledgeApplyType,
  85. WorkFlowApplyStatus = EKnowledgeWorkFlowStatus.Auditing,
  86. };
  87. return await _knowledgeWorkFlowRepository.AddAsync(workFlow, cancellationToken);
  88. }
  89. /// <summary>
  90. /// 修改流程ID
  91. /// </summary>
  92. /// <param name="assignInfo"></param>
  93. /// <param name="knowledgeFlowId"></param>
  94. /// <param name="workFlowId"></param>
  95. /// <param name="cancellationToken"></param>
  96. /// <returns></returns>
  97. public async Task UpdateWorkFlowId(FlowAssignInfo assignInfo, string? knowledgeFlowId, string workFlowId, CancellationToken cancellationToken)
  98. {
  99. if (string.IsNullOrEmpty(knowledgeFlowId))
  100. throw UserFriendlyException.SameMessage("无效知识编号");
  101. var knowledgeFlow =
  102. await _knowledgeWorkFlowRepository.GetAsync(knowledgeFlowId, cancellationToken);
  103. if (knowledgeFlow == null)
  104. throw new UserFriendlyException($"无效知识编号, knowledgeFlowId: {knowledgeFlowId}", "无效知识编号");
  105. knowledgeFlow.WorkflowId = workFlowId;
  106. knowledgeFlow.Assign(assignInfo.FlowAssignType, assignInfo.GetHandlerIds());
  107. await _knowledgeWorkFlowRepository.UpdateAsync(knowledgeFlow, cancellationToken);
  108. var knowledge = await _knowledgeRepository.GetAsync(knowledgeFlow.KnowledgeId, cancellationToken);
  109. if (knowledge == null)
  110. throw new UserFriendlyException($"无效知识编号, knowledgeId: {knowledgeFlow.KnowledgeId}", "无效知识编号");
  111. knowledge.WorkflowId = workFlowId;
  112. knowledge.Status = EKnowledgeStatus.Auditing;
  113. knowledge.Assign(assignInfo.FlowAssignType, assignInfo.GetHandlerIds());
  114. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  115. }
  116. /// <summary>
  117. /// 修改指派人
  118. /// </summary>
  119. /// <param name="assignInfo"></param>
  120. /// <param name="knowledgeFlowId"></param>
  121. /// <param name="cancellationToken"></param>
  122. /// <returns></returns>
  123. public async Task UpdateWorkAssign(FlowAssignInfo assignInfo, string? knowledgeFlowId, CancellationToken cancellationToken)
  124. {
  125. //知识流程表
  126. var knowledgeFlow =
  127. await _knowledgeWorkFlowRepository.GetAsync(knowledgeFlowId, cancellationToken);
  128. if (knowledgeFlow == null)
  129. throw new UserFriendlyException($"无效知识编号, knowledgeFlowId: {knowledgeFlowId}", "指派失败");
  130. knowledgeFlow.Assign(assignInfo.FlowAssignType, assignInfo.GetHandlerIds());
  131. await _knowledgeWorkFlowRepository.UpdateAsync(knowledgeFlow, cancellationToken);
  132. //知识主表
  133. var knowledge = await _knowledgeRepository.GetAsync(p => p.WorkflowId == knowledgeFlow.WorkflowId, cancellationToken);
  134. if (knowledge != null)
  135. {
  136. knowledge.Assign(assignInfo.FlowAssignType, assignInfo.GetHandlerIds());
  137. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  138. }
  139. }
  140. /// <summary>
  141. /// 知识库-新增
  142. /// </summary>
  143. /// <param name="dto"></param>
  144. /// <returns></returns>
  145. public async Task<string> KnowledgeAdd(AddKnowledgeDto dto, CancellationToken cancellationToken)
  146. {
  147. var kn = _mapper.Map<Knowledge>(dto);
  148. //Code为空,从新生成Code
  149. if (string.IsNullOrEmpty(kn.Code))
  150. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  151. kn.Status = EKnowledgeStatus.Auditing;
  152. return await _knowledgeRepository.AddAsync(kn, cancellationToken);
  153. }
  154. /// <summary>
  155. /// 知识库-修改
  156. /// </summary>
  157. /// <param name="dto"></param>
  158. /// <returns></returns>
  159. public async Task<string> KnowledgeUpdate(UpdateKnowledgeDto dto, CancellationToken cancellationToken)
  160. {
  161. //知识修改逻辑
  162. //如果可以修改,此条数据不动,重新写入一条新数据,知识编号不变,版本号+1,审批通过以后在数据交换
  163. var know = await _knowledgeRepository.GetAsync(dto.Id, cancellationToken);
  164. if (know is null || know.IsDeleted)
  165. throw UserFriendlyException.SameMessage("无效知识");
  166. //审批中数据不能处理
  167. if (know.Status == EKnowledgeStatus.Auditing)
  168. throw UserFriendlyException.SameMessage("审批中数据不能修改");
  169. var knowledge = _mapper.Map<Knowledge>(dto);
  170. knowledge.Code = know.Code;
  171. knowledge.PageView = know.PageView;
  172. knowledge.Status = EKnowledgeStatus.Auditing;
  173. knowledge.Id = null;
  174. knowledge.Version = 0;
  175. return await _knowledgeRepository.AddAsync(knowledge, cancellationToken);
  176. }
  177. /// <summary>
  178. /// 流程终止,处理知识状态
  179. /// </summary>
  180. /// <param name="workflow"></param>
  181. /// <param name="cancellationToken"></param>
  182. /// <returns></returns>
  183. /// <exception cref="UserFriendlyException"></exception>
  184. public async Task TerminateWorkKnowledge(Workflow workflow, CancellationToken cancellationToken)
  185. {
  186. //修改主表审批状态 根据流程ID查询审批主表
  187. var workFlow = await _knowledgeWorkFlowRepository.GetAsync(p => p.WorkflowId == workflow.Id, cancellationToken);
  188. if (workFlow == null)
  189. throw new UserFriendlyException($"知识查询失败, workflowId: {workflow.Id}", "无效流程编号");
  190. //根据审批主表知识ID查询当前知识
  191. var knowledge = await _knowledgeRepository.GetAsync(p => p.Id == workFlow.KnowledgeId, cancellationToken);
  192. if (knowledge == null)
  193. throw new UserFriendlyException($"知识查询失败");
  194. //修改业务数据状态
  195. workFlow.WorkFlowApplyStatus = EKnowledgeWorkFlowStatus.Revoke;
  196. await _knowledgeWorkFlowRepository.UpdateAsync(workFlow);
  197. switch (workFlow.WorkflowModuleStatus)
  198. {
  199. case EKnowledgeApplyType.Add:
  200. //将知识保存为草稿
  201. var dto = _mapper.Map<AddKnowledgeDto>(knowledge);
  202. dto.Status = EKnowledgeStatus.Drafts;
  203. var tempKnow = _mapper.Map<Knowledge>(dto);
  204. await _knowledgeRepository.AddAsync(tempKnow, cancellationToken);
  205. //现有知识状态更改为已撤回
  206. knowledge.Status = EKnowledgeStatus.Revert;
  207. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  208. break;
  209. }
  210. }
  211. /// <summary>
  212. /// 流程审批完成,处理知识状态
  213. /// </summary>
  214. /// <param name="workflow"></param>
  215. /// <param name="cancellationToken"></param>
  216. /// <returns></returns>
  217. /// <exception cref="UserFriendlyException"></exception>
  218. public async Task EndWorkKnowledge(Workflow workflow, CancellationToken cancellationToken)
  219. {
  220. //修改主表审批状态 根据流程ID查询审批主表
  221. var workFlow = await _knowledgeWorkFlowRepository.GetAsync(p => p.WorkflowId == workflow.Id, cancellationToken);
  222. if (workFlow == null)
  223. throw new UserFriendlyException($"知识查询失败, workflowId: {workflow.Id}", "无效流程编号");
  224. //根据审批主表知识ID查询当前知识
  225. // var knowledge = await _knowledgeRepository.GetAsync(p => p.Id == workFlow.KnowledgeId, cancellationToken);
  226. var knowledge = await _knowledgeRepository.Queryable()
  227. .Includes(it => it.SystemOrganize)
  228. .Includes(it => it.HotspotType)
  229. .Includes(it => it.User)
  230. .Where(p => p.Id == workFlow.KnowledgeId)
  231. .FirstAsync();
  232. if (knowledge == null)
  233. throw new UserFriendlyException($"知识查询失败");
  234. workFlow.HandleTime = DateTime.Now;
  235. workFlow.WorkFlowApplyStatus = EKnowledgeWorkFlowStatus.Success;
  236. await _knowledgeWorkFlowRepository.UpdateAsync(workFlow, cancellationToken);
  237. string isSendType = "";//推送类别:新增0,修改1,删除2
  238. switch (workflow.ModuleCode)
  239. {
  240. case WorkflowModuleConsts.KnowledgeAdd://新增
  241. case WorkflowModuleConsts.KnowledgeUpdate://修改
  242. //根据Code查询是否有历史数据
  243. var oldKnowledge = await _knowledgeRepository
  244. .Queryable()
  245. .Where(p => p.Code == knowledge.Code && (p.Status == EKnowledgeStatus.OnShelf || p.Status == EKnowledgeStatus.OffShelf)
  246. && p.IsDeleted == false && p.Id != knowledge.Id)
  247. .OrderByDescending(p => p.Version)
  248. .Take(1)
  249. .FirstAsync();
  250. if (oldKnowledge == null)
  251. {
  252. knowledge.Version = 1;
  253. isSendType = "0";
  254. }
  255. else
  256. {
  257. knowledge.Version = oldKnowledge.Version + 1;
  258. knowledge.PageView = oldKnowledge.PageView;
  259. isSendType = "1";
  260. }
  261. //修改知识状态为已上架
  262. knowledge.Status = EKnowledgeStatus.OnShelf;
  263. knowledge.OnShelfTime = System.DateTime.Now;
  264. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  265. break;
  266. case WorkflowModuleConsts.KnowledgeDelete://删除
  267. //知识先下架,在删除
  268. knowledge.Status = EKnowledgeStatus.OffShelf;
  269. knowledge.OffShelfTime = System.DateTime.Now;
  270. knowledge.WorkflowId = workflow.Id;
  271. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  272. //删除知识
  273. await _knowledgeRepository.RemoveAsync(p => p.Code == knowledge.Code, true, cancellationToken);
  274. isSendType = "2";
  275. break;
  276. }
  277. #region 数据推送
  278. //推送
  279. if (isSendType == "0") //新增知识推送
  280. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeAdd, _mapper.Map<KnowledgeSendDto>(knowledge), cancellationToken: cancellationToken);
  281. else if (isSendType == "1") //修改知识推送
  282. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeUpdate, _mapper.Map<KnowledgeSendDto>(knowledge), cancellationToken: cancellationToken);
  283. else if (isSendType == "2") //删除知识推送
  284. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, _mapper.Map<KnowledgeSendDto>(knowledge), cancellationToken: cancellationToken);
  285. #endregion
  286. }
  287. }
  288. }