KnowledgeDomainService.cs 15 KB

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