KnowledgeController.cs 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691
  1. using DotNetCore.CAP;
  2. using Hotline.Api.Filter;
  3. using Hotline.Application.Bulletin;
  4. using Hotline.Application.ExportExcel;
  5. using Hotline.Application.ExportWord;
  6. using Hotline.Application.FlowEngine;
  7. using Hotline.Application.Knowledge;
  8. using Hotline.Application.Systems;
  9. using Hotline.Application.Tools;
  10. using Hotline.File;
  11. using Hotline.FlowEngine.WorkflowModules;
  12. using Hotline.FlowEngine.Workflows;
  13. using Hotline.KnowledgeBase;
  14. using Hotline.KnowledgeBase.Notifies;
  15. using Hotline.Repository.SqlSugar.Extensions;
  16. using Hotline.Repository.SqlSugar.Ts;
  17. using Hotline.Settings;
  18. using Hotline.Settings.Hotspots;
  19. using Hotline.Share.Dtos;
  20. using Hotline.Share.Dtos.FlowEngine;
  21. using Hotline.Share.Dtos.Knowledge;
  22. using Hotline.Share.Dtos.Order;
  23. using Hotline.Share.Enums.Article;
  24. using Hotline.Share.Enums.FlowEngine;
  25. using Hotline.Share.Enums.KnowledgeBase;
  26. using Hotline.Share.Mq;
  27. using Hotline.Share.Tools;
  28. using Hotline.Users;
  29. using Mapster;
  30. using MapsterMapper;
  31. using MediatR;
  32. using Microsoft.AspNetCore.Mvc;
  33. using SqlSugar;
  34. using System.Text;
  35. using Hotline.Configurations;
  36. using Microsoft.Extensions.Options;
  37. using XF.Domain.Authentications;
  38. using XF.Domain.Exceptions;
  39. using XF.Domain.Repository;
  40. using XF.Utility.EnumExtensions;
  41. namespace Hotline.Api.Controllers
  42. {
  43. public class KnowledgeController : BaseController
  44. {
  45. #region 注入
  46. private readonly IExportApplication _exportApplication;
  47. private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
  48. private readonly IRepository<KnowledgeApprove> _knowledgeApproRepository;
  49. private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
  50. private readonly IWordHelperService _wordHelperService;
  51. private readonly BaseDataApplication _baseDataApplication;
  52. private readonly IKnowledgeRepository _knowledgeRepository;
  53. private readonly ISessionContext _sessionContext;
  54. private readonly IKnowledgeDomainService _knowledgeDomainService;
  55. private readonly IMapper _mapper;
  56. private readonly IKnowApplication _knowApplication;
  57. private readonly IMediator _mediator;
  58. private readonly IWorkflowApplication _workflowApplication;
  59. private readonly IWorkflowDomainService _workflowDomainService;
  60. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  61. private readonly IRepository<User> _userRepository;
  62. private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
  63. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  64. private readonly IRepositoryTextSearch<KnowledgeTs> _repositoryts;
  65. private readonly IRepository<KnowledgeWord> _knowledgeWrodRepository;
  66. private readonly IRepository<KnowledgeQuestions> _knowledgeQuestionsRepository;
  67. private readonly IRepository<KnowledgeCorrection> _knowledgeCorrectionRepository;
  68. private readonly IRepository<KnowledgeCollect> _knowledgeCollectRepository;
  69. private readonly ISystemDomainService _systemDomainService;
  70. private readonly IRepository<KnowledgeComment> _knowledgeCommentRepository;
  71. private readonly ISystemOrganizeRepository _systemOrganizeRepository;
  72. private readonly IFileRepository _fileRepository;
  73. private readonly ICapPublisher _capPublisher;
  74. private readonly IRepository<KnowledgeRelationType> _knowledgeRelationTypeRepository;
  75. private readonly IBulletinApplication _bulletinApplication;
  76. private readonly IRepository<KnowledgeCollectGroup> _knowledgeCollectGroupRepository;
  77. private readonly IRepository<KnowledgePv> _knowledgePvepository;
  78. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  79. public KnowledgeController(
  80. IKnowledgeRepository knowledgeRepository,
  81. ISessionContext sessionContext,
  82. IKnowledgeDomainService knowledgeDomainService,
  83. IMapper mapper,
  84. IKnowApplication knowApplication,
  85. IMediator mediator,
  86. IWorkflowApplication workflowApplication,
  87. IWorkflowDomainService workflowDomainService,
  88. IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
  89. IRepository<User> userRepository,
  90. IRepository<KnowledgeType> knowledgeTypeRepository,
  91. IRepository<Hotspot> hotspotTypeRepository,
  92. IRepositoryTextSearch<KnowledgeTs> repositoryts,
  93. IRepository<KnowledgeWord> knowledgeWrodRepository,
  94. IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
  95. IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
  96. IRepository<KnowledgeCollect> knowledgeCollectRepository,
  97. ISystemDomainService systemDomainService,
  98. IRepository<KnowledgeComment> knowledgeCommentRepository,
  99. ISystemOrganizeRepository systemOrganizeRepository,
  100. IFileRepository fileRepository,
  101. ICapPublisher capPublisher,
  102. IRepository<KnowledgeRelationType> knowledgeRelationTypeRepository,
  103. IBulletinApplication bulletinApplication,
  104. IRepository<KnowledgeCollectGroup> knowledgeCollectGroupRepository,
  105. IExportApplication exportApplication,
  106. BaseDataApplication baseDataApplication,
  107. IWordHelperService wordHelperService,
  108. IRepository<KnowledgePv> knowledgePvepository,
  109. IRepository<KnowledgeWord> knowledgeWordRepository,
  110. IRepository<KnowledgeHotWord> knowledgeWordHotRepository,
  111. IOptionsSnapshot<AppConfiguration> appOptions,
  112. IRepository<KnowledgeHotWord> knowledgeHotWordRepository,
  113. IRepository<KnowledgeApprove> knowledgeApproRepository)
  114. {
  115. _knowledgeRepository = knowledgeRepository;
  116. _sessionContext = sessionContext;
  117. _knowledgeDomainService = knowledgeDomainService;
  118. _mapper = mapper;
  119. _knowApplication = knowApplication;
  120. _mediator = mediator;
  121. _workflowApplication = workflowApplication;
  122. _workflowDomainService = workflowDomainService;
  123. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  124. _userRepository = userRepository;
  125. _knowledgeTypeRepository = knowledgeTypeRepository;
  126. _hotspotTypeRepository = hotspotTypeRepository;
  127. _repositoryts = repositoryts;
  128. _knowledgeWrodRepository = knowledgeWrodRepository;
  129. _knowledgeQuestionsRepository = knowledgeQuestionsRepository;
  130. _knowledgeCorrectionRepository = knowledgeCorrectionRepository;
  131. _knowledgeCollectRepository = knowledgeCollectRepository;
  132. _systemDomainService = systemDomainService;
  133. _knowledgeCommentRepository = knowledgeCommentRepository;
  134. _systemOrganizeRepository = systemOrganizeRepository;
  135. _fileRepository = fileRepository;
  136. _capPublisher = capPublisher;
  137. _knowledgeRelationTypeRepository = knowledgeRelationTypeRepository;
  138. _bulletinApplication = bulletinApplication;
  139. _knowledgeCollectGroupRepository = knowledgeCollectGroupRepository;
  140. _exportApplication = exportApplication;
  141. _baseDataApplication = baseDataApplication;
  142. _wordHelperService = wordHelperService;
  143. _knowledgePvepository = knowledgePvepository;
  144. _knowledgeWordRepository = knowledgeWordRepository;
  145. _knowledgeHotWordRepository = knowledgeHotWordRepository;
  146. _knowledgeApproRepository = knowledgeApproRepository;
  147. _appOptions = appOptions;
  148. }
  149. #endregion
  150. #region 知识管理
  151. /// <summary>
  152. /// 知识库-新增
  153. /// </summary>
  154. /// <param name="dto"></param>
  155. /// <returns></returns>
  156. [HttpPost("add")]
  157. [LogFilter("知识新增")]
  158. public async Task<string> AddKnowledge([FromBody] AddStartFlowDto dto)
  159. {
  160. //var addDto = _mapper.Map<AddKnowledgeDto>(dto.Data);
  161. var kn = _mapper.Map<Knowledge>(dto.Data);
  162. kn.SourceOrganizeId = _sessionContext.RequiredOrgId;
  163. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == kn.Title).AnyAsync();
  164. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  165. //Code为空,从新生成Code
  166. if (string.IsNullOrEmpty(kn.Code))
  167. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  168. kn.Status = EKnowledgeStatus.Drafts;
  169. kn.InitId();
  170. if (dto.Data.Files.NotNullOrEmpty()) kn.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, kn.Id, "", HttpContext.RequestAborted);
  171. await _knowledgeRepository.AddAsync(kn, HttpContext.RequestAborted);
  172. if (dto.Data.KnowledgeType.Any())
  173. {
  174. List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
  175. types.ForEach(x => x.KnowledgeId = kn.Id);
  176. await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
  177. }
  178. if (dto.Workflow != null && !string.IsNullOrEmpty(kn.Id))
  179. {
  180. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  181. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  182. startDto.Title = "知识库新增";
  183. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, kn.Id, cancellationToken: HttpContext.RequestAborted);
  184. await StartFlow(kn.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  185. //var knowledge = await _knowledgeRepository.GetAsync(kn.Id);
  186. //knowledge.Status = EKnowledgeStatus.Auditing;
  187. //await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  188. }
  189. return kn.Id;
  190. }
  191. /// <summary>
  192. /// 知识库-新增(new)
  193. /// </summary>
  194. [HttpPost]
  195. public async Task<string> Add([FromBody] AddKnowledgeDto dto)
  196. {
  197. //add kn
  198. var kn = _mapper.Map<Knowledge>(dto);
  199. kn.SourceOrganizeId = _sessionContext.RequiredOrgId;
  200. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == kn.Title).AnyAsync();
  201. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  202. //Code为空,从新生成Code
  203. if (string.IsNullOrEmpty(kn.Code))
  204. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  205. kn.Status = EKnowledgeStatus.Drafts;
  206. kn.InitId();
  207. if (dto.Files.NotNullOrEmpty()) kn.FileJson = await _fileRepository.AddFileAsync(dto.Files, kn.Id, "", HttpContext.RequestAborted);
  208. //await _knowledgeRepository.AddAsync(kn, HttpContext.RequestAborted);
  209. if (dto.KnowledgeType.Any())
  210. {
  211. List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
  212. types.ForEach(x => x.KnowledgeId = kn.Id);
  213. await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
  214. }
  215. //发起新增审批
  216. var approveAdd = new KnowledgeApprove
  217. {
  218. KnowledgeId = kn.Id,
  219. KnowledgeApproveType = EKnowledgeApproveType.Add,
  220. KnowledgeApproveStatus = EKnowledgeApproveStatus.Unhandle,
  221. Knowledge = kn
  222. };
  223. await _knowledgeApproRepository.AddNav(approveAdd)
  224. .Include(d => d.Knowledge)
  225. .ExecuteCommandAsync();
  226. return kn.Id;
  227. }
  228. /// <summary>
  229. /// 知识库-知识下架
  230. /// </summary>
  231. /// <param name="Id"></param>
  232. /// <returns></returns>
  233. [HttpPut("offshelf")]
  234. [LogFilter("知识下架")]
  235. public async Task KnowledgeOffShelf([FromBody] OffShelfStartFlowDto dto)
  236. {
  237. var know = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
  238. if (know != null && know.Status == EKnowledgeStatus.OnShelf)
  239. {
  240. if (_sessionContext.OrgIsCenter || !_appOptions.Value.IsYiBin)
  241. {
  242. know.Status = EKnowledgeStatus.OffShelf;
  243. know.OnShelfTime = null;
  244. know.OffShelfTime = DateTime.Now;
  245. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  246. var pushKnowledge = _mapper.Map<KnowledgeSendDto>(know);
  247. pushKnowledge.CategoryCode = "01";
  248. pushKnowledge.CategoryName = "公共服务";
  249. //推省上
  250. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
  251. }
  252. else
  253. {
  254. know.Status = EKnowledgeStatus.OffShelfAudit;
  255. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  256. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  257. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeOffshelf;
  258. startDto.Opinion = dto.Data.Opinion;
  259. startDto.Title = "知识库下架";
  260. await StartFlow(know.Id, WorkflowModuleConsts.KnowledgeOffshelf, EKnowledgeApplyType.Offshelf, startDto);
  261. }
  262. }
  263. else
  264. throw UserFriendlyException.SameMessage("知识下架失败");
  265. }
  266. /// <summary>
  267. /// 知识库-知识上架
  268. /// </summary>
  269. /// <param name="Id"></param>
  270. /// <returns></returns>
  271. [HttpPut("ontheshelf")]
  272. [LogFilter("知识上架")]
  273. public async Task KnowledgeOnTheShelf(string Id)
  274. {
  275. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  276. if (know != null && know.Status == EKnowledgeStatus.OffShelf)
  277. {
  278. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == know.Title && x.Id != know.Id).AnyAsync();
  279. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  280. if (know.ExpiredTime < DateTime.Now) throw UserFriendlyException.SameMessage("知识已过期不能上架!");
  281. know.Status = EKnowledgeStatus.OnShelf;
  282. know.OnShelfTime = DateTime.Now;
  283. know.OffShelfTime = null;
  284. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  285. }
  286. else
  287. throw UserFriendlyException.SameMessage("知识上架失败");
  288. }
  289. /// <summary>
  290. /// 知识库-标题
  291. /// </summary>
  292. /// <param name="title"></param>
  293. /// <returns></returns>
  294. [HttpGet("title")]
  295. public async Task<bool> KnowledgeTitle([FromQuery] KnowledgeTitleDto dto)
  296. {
  297. var count = await _knowledgeRepository.Queryable()
  298. .WhereIF(!string.IsNullOrEmpty(dto.Id), x => x.Id != dto.Id)
  299. .Where(x => x.Title == dto.Title && x.Status == EKnowledgeStatus.OnShelf).CountAsync();
  300. return count > 0;
  301. }
  302. /// <summary>
  303. /// 知识库-修改
  304. /// </summary>
  305. /// <param name="dto"></param>
  306. /// <returns></returns>
  307. [HttpPut("update")]
  308. [LogFilter("知识修改")]
  309. public async Task UpdateKnowledge([FromBody] UpdateStartFlowDto dto)
  310. {
  311. var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id);
  312. if (knowledge == null)
  313. throw UserFriendlyException.SameMessage("知识库数据错误");
  314. if ((knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing) && (knowledge.ExpiredTime.HasValue && knowledge.ExpiredTime.Value > DateTime.Now))
  315. throw UserFriendlyException.SameMessage("知识库数据不可修改");
  316. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == dto.Data.Title && x.Id != dto.Data.Id).AnyAsync();
  317. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  318. _mapper.Map(dto.Data, knowledge);
  319. knowledge.HotspotId = dto.Data.HotspotId;
  320. knowledge.HotspotExternal = dto.Data.HotspotExternal;
  321. if (dto.Data.Files.Any())
  322. knowledge.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, knowledge.Id, "", HttpContext.RequestAborted);
  323. else
  324. knowledge.FileJson = new List<Share.Dtos.File.FileJson>();
  325. if (dto.Workflow != null) knowledge.Renewaln = knowledge.Status != EKnowledgeStatus.Drafts;
  326. if (_appOptions.Value.IsYiBin)
  327. {
  328. //临时处理 修改后提交修改基本信息
  329. if (!_sessionContext.OrgIsCenter)
  330. {
  331. knowledge.Attribution = "部门知识库";
  332. }
  333. knowledge.CreatorId = _sessionContext.UserId;
  334. knowledge.CreatorName = _sessionContext.UserName;
  335. knowledge.CreatorOrgId = _sessionContext.OrgId;
  336. knowledge.CreatorOrgName = _sessionContext.OrgName;
  337. knowledge.CreatorOrgLevel = _sessionContext.OrgLevel;
  338. }
  339. await _knowledgeRepository.UpdateNullAsync(knowledge, HttpContext.RequestAborted);
  340. if (dto.Data.KnowledgeType.Any())
  341. {
  342. var anyRelationTypes = await _knowledgeRelationTypeRepository.Queryable().Where(x => x.KnowledgeId == knowledge.Id).ToListAsync();
  343. if (anyRelationTypes.Any())
  344. await _knowledgeRelationTypeRepository.RemoveRangeAsync(anyRelationTypes);
  345. List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
  346. types.ForEach(x => x.KnowledgeId = dto.Data.Id);
  347. await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
  348. }
  349. if (dto.Workflow != null)
  350. {
  351. if (knowledge.Status == EKnowledgeStatus.Drafts)
  352. {
  353. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  354. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  355. startDto.Title = "知识库新增";
  356. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  357. await StartFlow(knowledge.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  358. }
  359. else
  360. {
  361. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  362. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeUpdate;
  363. startDto.Title = "知识库修改";
  364. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  365. await StartFlow(knowledge.Id, WorkflowModuleConsts.KnowledgeUpdate, EKnowledgeApplyType.Update, startDto);
  366. }
  367. }
  368. }
  369. /// <summary>
  370. /// 知识库-修改(new)
  371. /// </summary>
  372. /// <param name="dto"></param>
  373. /// <returns></returns>
  374. [HttpPut]
  375. [LogFilter("知识修改")]
  376. public async Task UpdateKnowledge([FromBody] UpdateKnowledgeDto dto)
  377. {
  378. }
  379. /// <summary>
  380. /// 批量审核
  381. /// </summary>
  382. /// <returns></returns>
  383. [HttpPost("batch_audit")]
  384. public async Task<string> KnowledgeBatchAuditAsync([FromBody] KnowledgeBatchAuditInDto dto)
  385. {
  386. var result = new StringBuilder();
  387. var fail = 0;
  388. var success = 0;
  389. var nextWorkflowDto = new NextWorkflowDto
  390. {
  391. IsSms = dto.IsSms,
  392. ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed,
  393. Opinion = dto.Opinion
  394. };
  395. foreach (var knowledgeId in dto.KnowledgeIds)
  396. {
  397. try
  398. {
  399. var knowledge = await _knowledgeDomainService.KnowledgeInfo(knowledgeId, HttpContext.RequestAborted);
  400. nextWorkflowDto.WorkflowId = knowledge.WorkflowId;
  401. NextStepsWithOpinionDto<NextStepOption> next = null;
  402. try
  403. {
  404. next = await _workflowApplication.GetNextStepsAsync(knowledge.WorkflowId, HttpContext.RequestAborted);
  405. }
  406. catch (UserFriendlyException e)
  407. {
  408. if (e.Message.Contains("未找到对应节点"))
  409. {
  410. result.Append("无权审核:" + knowledge.Title);
  411. fail++;
  412. }
  413. else
  414. {
  415. throw;
  416. }
  417. }
  418. if (next == null) continue;
  419. nextWorkflowDto.StepId = next.StepId;
  420. nextWorkflowDto.NextStepCode = next.Steps.First().Key;
  421. nextWorkflowDto.NextStepName = next.Steps.First().Value;
  422. if (dto.IsPass)
  423. await _workflowDomainService.NextAsync(_sessionContext, nextWorkflowDto,
  424. cancellationToken: HttpContext.RequestAborted);
  425. else
  426. {
  427. var reject = nextWorkflowDto.Adapt<RejectDto>();
  428. await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
  429. }
  430. success++;
  431. }
  432. catch (UserFriendlyException e)
  433. {
  434. result.Append(e.Message);
  435. fail++;
  436. }
  437. }
  438. return $"总共: {dto.KnowledgeIds.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
  439. }
  440. /// <summary>
  441. /// 根据知识标题自动分词并保存到关键词表中
  442. /// </summary>
  443. /// <param name="title"></param>
  444. /// <returns></returns>
  445. [HttpGet("participle")]
  446. public async Task<IList<KnowledgeWordOutDto>> KnowledgeKeyWord([FromQuery] string title)
  447. {
  448. return await _knowApplication.TitleParticiple(title);
  449. }
  450. /// <summary>
  451. /// 删除知识
  452. /// </summary>
  453. /// <param name="id"></param>
  454. /// <returns></returns>
  455. [HttpDelete]
  456. [LogFilter("删除知识")]
  457. public async Task Remove([FromBody] DeleteStartFlowDto dto)
  458. {
  459. //var delete = _mapper.Map<KnowledgeDto>(dto.Data);
  460. var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
  461. if (knowledge == null)
  462. throw UserFriendlyException.SameMessage("无效知识库数据");
  463. if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
  464. throw UserFriendlyException.SameMessage("知识库数据不可删除");
  465. if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
  466. {
  467. await _knowledgeRepository.RemoveAsync(knowledge, false, HttpContext.RequestAborted);
  468. }
  469. else
  470. {
  471. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  472. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeDelete;
  473. startDto.Title = "知识库删除";
  474. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  475. await StartFlow(dto.Data.Id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, startDto);
  476. }
  477. }
  478. /// <summary>
  479. /// 增加搜索量
  480. /// </summary>
  481. /// <param name="dto"></param>
  482. /// <returns></returns>
  483. [HttpPost("search_num")]
  484. [LogFilter("知识搜索")]
  485. public async Task SearchNum([FromBody] KnowledgeSearchNumDto dto)
  486. {
  487. var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  488. if (knowledge == null)
  489. throw UserFriendlyException.SameMessage("无效知识库数据");
  490. knowledge.SearchNum++;
  491. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  492. }
  493. /// <summary>
  494. /// 搜索量列表
  495. /// </summary>
  496. /// <param name="dto"></param>
  497. /// <returns></returns>
  498. [HttpGet("search_num/list")]
  499. public async Task<PagedDto<KnowledgeDto>> SearchNumList([FromQuery] KnowledgeCollectListDto dto)
  500. {
  501. var query = _knowledgeRepository.Queryable(false, true, false)
  502. .Where(x => x.Status == EKnowledgeStatus.OnShelf)
  503. .Where(m => m.IsDeleted == false)
  504. .Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  505. .OrderByDescending(x => x.SearchNum);
  506. if (_sessionContext.OrgIsCenter == false)
  507. {
  508. query = query.Where(m => m.KnowledgeType.Any(a => a.IsDeleted == false && a.KnowledgeType.KnowledgeTypeOrgs
  509. .Any(k => k.IsDeleted == false && k.OrgId.StartsWith(_sessionContext.OrgId))));
  510. query = query.Where(m => m.Attribution == "部门知识库");
  511. }
  512. var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  513. return new PagedDto<KnowledgeDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDto>>(items));
  514. }
  515. /// <summary>
  516. /// 知识库-知识修改-查询详情
  517. /// </summary>
  518. /// <param name="Id"></param>
  519. /// <returns></returns>
  520. [HttpGet("updateinfo/{Id}")]
  521. public async Task<KnowledgeInfoDto> KnowledgeUpdateInfo(string Id)
  522. {
  523. //var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  524. var know = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
  525. if (know is null)
  526. throw UserFriendlyException.SameMessage("知识查询失败!");
  527. var knowledgeInfoDto = _mapper.Map<KnowledgeInfoDto>(know);
  528. if (knowledgeInfoDto != null && !string.IsNullOrEmpty(knowledgeInfoDto.Content))
  529. knowledgeInfoDto.Content = _bulletinApplication.GetSiteUrls(knowledgeInfoDto.Content);
  530. //分类
  531. //var type = await _knowledgeTypeRepository.GetAsync(know.KnowledgeTypeId, HttpContext.RequestAborted);
  532. //if (type != null)
  533. // knowledgeInfoDto.KnowledgeTypeName = type.SpliceName;
  534. //热点
  535. var hot = await _hotspotTypeRepository.GetAsync(know.HotspotId, HttpContext.RequestAborted);
  536. if (hot != null)
  537. knowledgeInfoDto.HotspotName = hot.HotSpotFullName;
  538. //收藏
  539. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  540. if (collect != null)
  541. knowledgeInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  542. return knowledgeInfoDto;
  543. }
  544. /// <summary>
  545. /// 知识库-查询详情-增加浏览量
  546. /// </summary>
  547. /// <param name="Id">知识Id</param>
  548. /// <param name="IsAddPv">默认不增加,false不增加,true增加浏览量</param>
  549. /// <returns></returns>
  550. [HttpGet("info/{Id}")]
  551. public async Task<KnowledgeInfoDto> KnowledgeInfo(string Id, bool? IsAddPv)
  552. {
  553. var knowledge = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
  554. if (knowledge is null)
  555. throw UserFriendlyException.SameMessage("知识查询失败!");
  556. if (knowledge.Workflow != null)
  557. knowledge.IsCanHandle = knowledge.Workflow.IsCanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles);
  558. //转化
  559. var knowledgeShowInfoDto = _mapper.Map<KnowledgeInfoDto>(knowledge);
  560. if (knowledgeShowInfoDto != null && !string.IsNullOrEmpty(knowledgeShowInfoDto.Content))
  561. knowledgeShowInfoDto.Content = _bulletinApplication.GetSiteUrls(knowledgeShowInfoDto.Content);
  562. //var type = await _knowledgeTypeRepository.GetAsync(knowledge.KnowledgeTypeId, HttpContext.RequestAborted);
  563. //if (type != null)
  564. //{
  565. // knowledgeShowInfoDto.KnowledgeTypeName = type.SpliceName;
  566. // knowledgeShowInfoDto.KnowledgeType = _mapper.Map<KnowledgeTypeDto>(type);
  567. //}
  568. var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
  569. if (hot != null)
  570. knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
  571. //收藏
  572. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  573. if (collect != null)
  574. knowledgeShowInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  575. //关联知识
  576. 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();
  577. if (knowledges.Any())
  578. knowledgeShowInfoDto.KnowledgeDtos = _mapper.Map<List<KnowledgeDto>>(knowledges);
  579. //关键词
  580. var knowledgeWords = await _knowledgeWrodRepository.Queryable().In(x => x.Id, knowledge.Keywords).ToListAsync();
  581. if (knowledgeWords.Any())
  582. knowledgeShowInfoDto.KeywordsDto = _mapper.Map<List<KnowledgeWordDto>>(knowledgeWords);
  583. if (knowledgeShowInfoDto.FileJson != null && knowledgeShowInfoDto.FileJson.Any())
  584. {
  585. var ids = knowledgeShowInfoDto.FileJson.Select(x => x.Id).ToList();
  586. knowledgeShowInfoDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
  587. }
  588. //var files = await _fileRepository.Queryable().Where(x => x.Key == knowledge.Id).ToListAsync();
  589. // if (files.Any()) knowledgeShowInfoDto.Files = _mapper.Map<List<FileDto>>(files);
  590. if (IsAddPv == true)
  591. _mediator.Publish(new GetKnowledgeInfoNotify(knowledge));
  592. return knowledgeShowInfoDto;
  593. }
  594. /// <summary>
  595. /// 知识详情--导出
  596. /// </summary>
  597. /// <param name="dto"></param>
  598. /// <returns></returns>
  599. [HttpPost("info/export")]
  600. public async Task<IActionResult> KnowledgeInfoExport([FromBody] KnowledgeInfoExportInDto dto)
  601. {
  602. if (dto.Ids.Length > 1)
  603. {
  604. var streams = await _knowApplication.KnowledgeInfoListExportAsync(dto, HttpContext.RequestAborted);
  605. byte[] fileBytes = _wordHelperService.ConvertZipStream(streams);
  606. var name = DateTime.Now.ToString("yyyyMMddHHmmss");
  607. return File(fileBytes, "application/octet-stream", $"{name}.zip");
  608. }
  609. var info = await _knowledgeRepository.GetAsync(dto.Ids[0]) ?? throw UserFriendlyException.SameMessage("知识不存在");
  610. return info.Content.HtmlToStream(dto.FileType).GetFileStreamResult(dto.FileType, info.Title, false);
  611. }
  612. /// <summary>
  613. /// 知识申请-关联知识-获取知识列表
  614. /// </summary>
  615. /// <returns></returns>
  616. [HttpGet("getknowledge")]
  617. public async Task<IReadOnlyList<KnowledgeCreateBMDataDto>> GetKnowledge()
  618. {
  619. var temp = await _knowledgeRepository
  620. .Queryable()
  621. .LeftJoin<SystemOrganize>((o, sys) => o.CreatorOrgId == sys.Id)
  622. //重新构建数据
  623. .Select((o, sys) => new
  624. {
  625. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  626. DepartmentId = sys.Id,
  627. Department = sys.Name,
  628. o.Id,
  629. o.Title,
  630. o.Status,
  631. o.Code,
  632. o.IsDeleted,
  633. o.ExpiredTime
  634. })
  635. //将结果合并成一个表
  636. .MergeTable()
  637. //取第一条数据
  638. .Where(x => x.IsDeleted == false)
  639. .Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  640. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  641. .ToListAsync();
  642. //返回数据
  643. return _mapper.Map<IReadOnlyList<KnowledgeCreateBMDataDto>>(temp);
  644. }
  645. /// <summary>
  646. /// 我的草稿箱
  647. /// </summary>
  648. /// <param name="pagedDto"></param>
  649. /// <returns></returns>
  650. [HttpGet("mydraftslist")]
  651. public async Task<PagedDto<KnowledgeDataDto>> MyDraftsList([FromQuery] MyDraftsListPagedDto pagedDto)
  652. {
  653. var (total, items) = await _knowledgeRepository
  654. .Queryable()
  655. .Includes(it => it.User)
  656. .Where(p => p.CreatorId == _sessionContext.RequiredUserId && p.Status == EKnowledgeStatus.Drafts)
  657. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  658. .WhereIF(pagedDto.StartTime != null, d => d.CreationTime >= pagedDto.StartTime)
  659. .WhereIF(pagedDto.EndTime != null, d => d.CreationTime <= pagedDto.EndTime)
  660. .OrderByDescending(p => p.CreationTime)
  661. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  662. return new PagedDto<KnowledgeDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(items));
  663. }
  664. /// <summary>
  665. /// 知识库列表页面枚举值
  666. /// </summary>
  667. /// <returns></returns>
  668. [HttpGet("knowledge-status-data")]
  669. public Dictionary<string, dynamic> KnowledgeStatus()
  670. {
  671. var tabNames = new List<KeyValuePair<int, string>>
  672. {
  673. new KeyValuePair<int, string>(3, "已上架"),
  674. new KeyValuePair<int, string>(4, "已下架"),
  675. new KeyValuePair<int, string>(1, "审核中"),
  676. new KeyValuePair<int, string>(8, "草稿"),
  677. new KeyValuePair<int, string>(-1, "全部")
  678. };
  679. var tabNewDraftsNames = new List<KeyValuePair<int, string>>
  680. {
  681. new KeyValuePair<int, string>(-1, "全部"),
  682. new KeyValuePair<int, string>(0, "待提交"),
  683. new KeyValuePair<int, string>(5, "审核不通过"),
  684. };
  685. var tabAuditingNames = new List<KeyValuePair<string, string>>
  686. {
  687. new KeyValuePair<string, string>("", "全部"),
  688. new KeyValuePair<string, string>("KnowledgeAdd", "新增审核"),
  689. new KeyValuePair<string, string>("KnowledgeUpdate", "修改审核"),
  690. new KeyValuePair<string, string>("KnowledgeDelete", "删除审核"),
  691. new KeyValuePair<string, string>("KnowledgeOffshelf", "下架审核"),
  692. };
  693. //return _baseDataApplication
  694. // .FileType(EFileType.excel | EFileType.pdf)
  695. // .Build();
  696. var ignoreFileType = EFileType.excel | EFileType.pdf;
  697. var items = EnumExts.GetDescriptions<EFileType>();
  698. var filteredDictionary = items
  699. .Where(kvp => (ignoreFileType & (EFileType)kvp.Key) == 0)
  700. .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
  701. .ToList();
  702. return new Dictionary<string, dynamic>
  703. {
  704. { "fileType", filteredDictionary},
  705. { "tabNames", tabNames },
  706. { "tabNewDraftsNames", tabNewDraftsNames },
  707. { "tabAuditingNames", tabAuditingNames }
  708. };
  709. }
  710. /// <summary>
  711. /// 知识查询
  712. /// </summary>
  713. /// <param name="pagedDto"></param>
  714. /// <returns></returns>
  715. [HttpGet]
  716. public async Task<PagedDto<KnowledgeDataDto>> GetKnowList([FromQuery] KnowPagedListDto pagedDto)
  717. {
  718. return (await _knowApplication.GetKnowList(pagedDto, HttpContext.RequestAborted))
  719. .ToPaged();
  720. }
  721. /// <summary>
  722. /// 知识查询-导出
  723. /// </summary>
  724. /// <param name="dto"></param>
  725. /// <returns></returns>
  726. [HttpPost("export")]
  727. public async Task<IActionResult> GetKnowListExportAsync([FromBody] ExportExcelDto<KnowPagedListDto> dto)
  728. {
  729. var items = (await _knowApplication.GetKnowList(dto.QueryDto, HttpContext.RequestAborted)).Item2;
  730. return _exportApplication.GetExcelFile(dto, items, "知识明细导出");
  731. }
  732. /// <summary>
  733. /// 来电弹窗知识检索
  734. /// </summary>
  735. /// <param name="dto"></param>
  736. /// <returns></returns>
  737. [HttpPost("knowretrieval")]
  738. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrievalWindow([FromBody] KnowledgeRetrievalPagedListDto dto)
  739. {
  740. return (await _knowApplication.KnowRetrievalAsync(dto)).ToPaged();
  741. }
  742. /// <summary>
  743. /// 知识检索
  744. /// </summary>
  745. /// <param name="dto"></param>
  746. /// <returns></returns>
  747. [HttpGet("knowretrieval")]
  748. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrieval([FromQuery] KnowledgeRetrievalPagedListDto dto)
  749. {
  750. return (await _knowApplication.KnowRetrievalAsync(dto)).ToPaged();
  751. }
  752. /// <summary>
  753. /// 知识检索页面基础数据
  754. /// </summary>
  755. /// <returns></returns>
  756. [HttpGet("knowretrieval/base_data")]
  757. public Dictionary<string, dynamic> GetKnowretrievalBaseData()
  758. {
  759. //return _baseDataApplication
  760. // .KnowledgeRetrievalType(new[] { 3, 4 })
  761. // .Build();
  762. var ignoreFileType = new[] { 3, 4 };
  763. return new Dictionary<string, dynamic>
  764. {
  765. { "knowledgeRetrievalType", EnumExts.GetDescriptions<EKnowledgeRetrievalType>().Where(m => !ignoreFileType.Contains(m.Key)).ToList() }
  766. };
  767. }
  768. /// <summary>
  769. /// 获取知识审批信息
  770. /// </summary>
  771. /// <param name="id"></param>
  772. /// <returns></returns>
  773. [HttpGet("audit_log")]
  774. public async Task<PagedDto<KnowledgeWorkFlowDto>> KnowRetrieval([FromQuery] AuditLogListPagedDto pagedDto)
  775. {
  776. var (total, temp) = await _knowledgeWorkFlowRepository
  777. .Queryable()
  778. .Includes(x => x.User)
  779. .Includes(x => x.SystemOrganize)
  780. .Includes(x => x.Workflow)
  781. .Where(x => x.KnowledgeId == pagedDto.id)
  782. .Where(x => x.IsDeleted == false)
  783. .OrderBy(x => x.CreationTime)
  784. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  785. return new PagedDto<KnowledgeWorkFlowDto>(total, _mapper.Map<IReadOnlyList<KnowledgeWorkFlowDto>>(temp));
  786. }
  787. /// <summary>
  788. /// 知识查重
  789. /// </summary>
  790. /// <param name="id"></param>
  791. /// <returns></returns>
  792. [HttpPost("finding_duplicate")]
  793. public async Task<bool> FindingDuplicate([FromBody] KnowledgeFindingDuplicateDto dto)
  794. {
  795. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.Auditing || x.Status >= EKnowledgeStatus.OnShelf)
  796. .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Equals(dto.Title))
  797. .WhereIF(!string.IsNullOrEmpty(dto.Summary), x => x.Summary.Equals(dto.Summary))
  798. .WhereIF(!string.IsNullOrEmpty(dto.Content), x => x.Content.Equals(dto.Content))
  799. .WhereIF(!string.IsNullOrEmpty(dto.Id), x => x.Id != dto.Id)
  800. .AnyAsync();
  801. return any;
  802. }
  803. #endregion
  804. #region 我的知识删除列表
  805. /// <summary>
  806. /// 我的知识删除列表页面枚举值
  807. /// </summary>
  808. /// <returns></returns>
  809. [HttpGet("delete-status-data")]
  810. public async Task<object> DeleteApplyStatus()
  811. {
  812. return EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>();
  813. }
  814. /// <summary>
  815. /// 我的知识删除列表
  816. /// </summary>
  817. /// <param name="pagedDto"></param>
  818. /// <returns></returns>
  819. [HttpGet("deletelist")]
  820. public async Task<PagedDto<KnowledgeDeleteApplyDataDto>> GetDeleteApplyList([FromQuery] KnowledgeDeletelPagedListDto pagedDto)
  821. {
  822. var (total, items) = await _knowledgeWorkFlowRepository
  823. .Queryable(includeDeleted: true)
  824. .Includes(it => it.Knowledge)
  825. .Includes(it => it.User)
  826. .Includes(it => it.SystemOrganize)
  827. .Includes(it => it.Knowledge, it => it.KnowledgeType)
  828. .Includes(it => it.Knowledge, it => it.HotspotType)
  829. .Includes(it => it.Workflow)
  830. .Where(d => d.CreatorId == _sessionContext.RequiredUserId && d.WorkflowModuleStatus == EKnowledgeApplyType.Delete && d.WorkflowId != null)
  831. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  832. .WhereIF(pagedDto.StartApplyTime.HasValue, d => d.CreationTime >= pagedDto.StartApplyTime)
  833. .WhereIF(pagedDto.EndApplyTime.HasValue, d => d.CreationTime <= pagedDto.EndApplyTime)
  834. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  835. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  836. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  837. .OrderByDescending(p => p.CreationTime)
  838. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  839. return new PagedDto<KnowledgeDeleteApplyDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDeleteApplyDataDto>>(items));
  840. }
  841. /// <summary>
  842. /// 审核管理页面枚举值
  843. /// </summary>
  844. /// <returns></returns>
  845. [HttpGet("approval-base-data")]
  846. public async Task<object> ApprovalBaseData()
  847. {
  848. return new
  849. {
  850. EKnowledgeWorkFlowStatus = EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>(),
  851. EKnowledgeApplyType = EnumExts.GetDescriptions<EKnowledgeApplyType>()
  852. };
  853. }
  854. /// <summary>
  855. /// 审核管理
  856. /// </summary>
  857. /// <param name="pagedDto"></param>
  858. /// <returns></returns>
  859. [HttpGet("approvedlist")]
  860. public async Task<PagedDto<KnowledgeApprovalDataDto>> ApprovedList([FromQuery] KnowledgeApprovalPagedListDto pagedDto)
  861. {
  862. var (total, items) = await _knowledgeWorkFlowRepository
  863. .Queryable(includeDeleted: true)
  864. .Includes(it => it.Knowledge)
  865. .Includes(it => it.User)
  866. .Includes(it => it.SystemOrganize)
  867. .Includes(it => it.Workflow, d => d.Steps)
  868. .Where(it => it.WorkflowId != null)
  869. .WhereIF(pagedDto.EKnowledgeApplyType.HasValue, d => d.WorkflowModuleStatus == pagedDto.EKnowledgeApplyType)
  870. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  871. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  872. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  873. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  874. .OrderByDescending(p => p.CreationTime)
  875. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  876. foreach (var item in items)
  877. {
  878. if (item.Workflow != null)
  879. //item.CanHandle = item.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
  880. item.CanHandle = item.Workflow.IsCanHandle(
  881. _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles);
  882. }
  883. //处理是否可以办理
  884. //items.ForEach(d => d.CanHandle = d.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgCode));
  885. return new PagedDto<KnowledgeApprovalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApprovalDataDto>>(items));
  886. }
  887. /// <summary>
  888. /// 工单受理知识检索
  889. /// </summary>
  890. /// <param name="pagedDto"></param>
  891. /// <returns></returns>
  892. [HttpGet("knowpopscreen")]
  893. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowPopScreen([FromQuery] KnowledgePopScreenPagedListDto pagedDto)
  894. {
  895. var orgid = string.Empty;
  896. if (pagedDto.RetrievalType == EKnowledgeRetrievalType.Org && !string.IsNullOrEmpty(pagedDto.Keyword))
  897. {
  898. var organize = await _systemOrganizeRepository.GetAsync(x => x.Name == pagedDto.Keyword);
  899. orgid = organize?.Id;
  900. }
  901. var (total, temp) = await _knowledgeRepository.Queryable()
  902. .Includes(x => x.SourceOrganize)
  903. .Where(d => d.Status == EKnowledgeStatus.OnShelf)
  904. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Title && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  905. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Content && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Content.Contains(pagedDto.Keyword!))
  906. .WhereIF(!string.IsNullOrEmpty(orgid) && pagedDto.RetrievalType == EKnowledgeRetrievalType.Org, x => x.CreatorOrgId.EndsWith(orgid!))
  907. .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotId), p => p.HotspotId == pagedDto.HotspotId)
  908. .OrderByDescending(p => p.CreationTime)
  909. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  910. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  911. }
  912. ///// <summary>
  913. ///// 新增-开始流程
  914. ///// </summary>
  915. ///// <param name="id">知识id</param>
  916. ///// <param name="dto">流程开启参数</param>
  917. ///// <returns></returns>
  918. //[HttpPost("{id}/add-startflow")]
  919. //public async Task AddStartFlow(string id, [FromBody] StartWorkflowDto dto)
  920. //{
  921. // await StartFlow(id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, dto);
  922. //}
  923. ///// <summary>
  924. ///// 删除-开始流程
  925. ///// </summary>
  926. ///// <param name="id">知识id</param>
  927. ///// <param name="dto">流程开启参数</param>
  928. ///// <returns></returns>
  929. //[HttpPost("{id}/remove-startflow")]
  930. //public async Task RemoveStartFlow(string id, [FromBody] StartWorkflowDto dto)
  931. //{
  932. // await StartFlow(id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, dto);
  933. //}
  934. /// <summary>
  935. /// 查询知识库办理流程开启参数-新增
  936. /// </summary>
  937. /// <returns></returns>
  938. [HttpGet("add-flow-start")]
  939. public async Task<NextStepsDto> GetAddFlowStartOptionsAsync()
  940. {
  941. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeAdd,
  942. HttpContext.RequestAborted);
  943. }
  944. /// <summary>
  945. /// 查询知识库办理流程开启参数-新增
  946. /// </summary>
  947. /// <returns></returns>
  948. [HttpGet("update-flow-start")]
  949. public async Task<NextStepsDto> GetUpdateFlowStartOptionsAsync()
  950. {
  951. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeUpdate,
  952. HttpContext.RequestAborted);
  953. }
  954. /// <summary>
  955. /// 查询知识库办理流程开启参数-删除
  956. /// </summary>
  957. /// <returns></returns>
  958. [HttpGet("remove-flow-start")]
  959. public async Task<NextStepsDto> GetRemoveFlowStartOptionsAsync()
  960. {
  961. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeDelete,
  962. HttpContext.RequestAborted);
  963. }
  964. /// <summary>
  965. /// 查询知识库办理流程开启参数-下架
  966. /// </summary>
  967. /// <returns></returns>
  968. [HttpGet("offshelf-flow-start")]
  969. public async Task<NextStepsDto> GetOffshelfFlowStartOptionsAsync()
  970. {
  971. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeOffshelf,
  972. HttpContext.RequestAborted);
  973. }
  974. /// <summary>
  975. /// 开始流程
  976. /// </summary>
  977. /// <param name="id">知识ID</param>
  978. /// <param name="moduleCode">知识模板编号</param>
  979. /// <param name="eKnowledgeApplyType">申请类型</param>
  980. /// <param name="dto">流程开启参数</param>
  981. /// <returns></returns>
  982. private async Task<string> StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
  983. {
  984. var knowledge = await _knowledgeRepository.GetAsync(id, HttpContext.RequestAborted);
  985. if (knowledge == null)
  986. throw UserFriendlyException.SameMessage("无效知识编号");
  987. if (eKnowledgeApplyType == EKnowledgeApplyType.Delete)
  988. {
  989. if (knowledge.IsDeleted == true)
  990. throw UserFriendlyException.SameMessage("知识删除失败");
  991. }
  992. //知识审批主表
  993. await _knowledgeDomainService.AddWorkFlowAsync(id, eKnowledgeApplyType, HttpContext.RequestAborted);
  994. dto.DefinitionModuleCode = moduleCode;
  995. //dto.Title = knowledge.Title;
  996. return await _workflowApplication.StartWorkflowAsync(dto, id, cancellationToken: HttpContext.RequestAborted);
  997. }
  998. #endregion
  999. #region 知识库词库
  1000. /// <summary>
  1001. /// 新增知识库词库
  1002. /// </summary>
  1003. /// <param name="dtos"></param>
  1004. /// <returns></returns>
  1005. [HttpPost("knowledge_word")]
  1006. [LogFilter("新增知识库词库")]
  1007. public async Task Add([FromBody] KnowledgeWordAddDto dto)
  1008. {
  1009. var word = _mapper.Map<KnowledgeWord>(dto);
  1010. await _knowledgeWrodRepository.AddAsync(word, HttpContext.RequestAborted);
  1011. }
  1012. /// <summary>
  1013. /// 删除知识库词库
  1014. /// </summary>
  1015. /// <param name="dto"></param>
  1016. /// <returns></returns>
  1017. [HttpDelete("knowledge_word")]
  1018. [LogFilter("删除知识库词库")]
  1019. public async Task Delete([FromBody] KnowledgeWordDeleteDto dto)
  1020. {
  1021. await _knowledgeRepository.RemoveKnowledgeWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
  1022. }
  1023. /// <summary>
  1024. /// 更新知识库词库
  1025. /// </summary>
  1026. /// <param name="dto"></param>
  1027. /// <returns></returns>
  1028. [HttpPut("knowledge_word")]
  1029. [LogFilter("更新知识库词库")]
  1030. public async Task Update([FromBody] KnowledgeWordUpdateDto dto)
  1031. {
  1032. var word = await _knowledgeWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1033. if (word is null)
  1034. throw UserFriendlyException.SameMessage("无效知识库词库");
  1035. _mapper.Map(dto, word);
  1036. word.LastModificationName = _sessionContext.UserName;
  1037. await _knowledgeWrodRepository.UpdateAsync(word, HttpContext.RequestAborted);
  1038. }
  1039. /// <summary>
  1040. /// 获取知识库词库列表
  1041. /// </summary>
  1042. /// <param name="dto"></param>
  1043. /// <returns></returns>
  1044. [HttpGet("knowledge_word/list")]
  1045. public async Task<PagedDto<KnowledgeWordDto>> List([FromQuery] KnowledgeWordListDto dto)
  1046. {
  1047. var (total, items) = await _knowledgeWrodRepository.Queryable()
  1048. .WhereIF(!string.IsNullOrEmpty(dto.Tag), x => x.Tag == dto.Tag!)
  1049. .WhereIF(!string.IsNullOrEmpty(dto.Classify), x => x.Classify == dto.Classify!)
  1050. .WhereIF(dto.IsEnable.HasValue, x => x.IsEnable == dto.IsEnable)
  1051. .WhereIF(!string.IsNullOrEmpty(dto.Synonym), x => x.Synonym != null && x.Synonym.Contains(dto.Synonym!))
  1052. .OrderByDescending(x => x.CreationTime)
  1053. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1054. return new PagedDto<KnowledgeWordDto>(total, _mapper.Map<IReadOnlyList<KnowledgeWordDto>>(items));
  1055. }
  1056. /// <summary>
  1057. /// 获取知识库词库
  1058. /// </summary>
  1059. /// <param name="id"></param>
  1060. /// <returns></returns>
  1061. [HttpGet("knowledge_word/{id}")]
  1062. public async Task<KnowledgeWord> WordEntity(string id)
  1063. {
  1064. return await _knowledgeWrodRepository.Queryable()
  1065. .FirstAsync(x => x.Id == id);
  1066. }
  1067. /// <summary>
  1068. /// 获取知识库词库基本信息
  1069. /// </summary>
  1070. /// <returns></returns>
  1071. [HttpGet("knowledge_word/base")]
  1072. public async Task<object> Base()
  1073. {
  1074. var rsp = new
  1075. {
  1076. KnowledgeWordClassify = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.KnowledgeWordClassify),
  1077. };
  1078. return rsp;
  1079. }
  1080. #endregion
  1081. #region 知识纠错
  1082. /// <summary>
  1083. /// 新增知识纠错
  1084. /// </summary>
  1085. /// <param name="dtos"></param>
  1086. /// <returns></returns>
  1087. [HttpPost("knowledge_correction")]
  1088. [LogFilter("新增知识纠错")]
  1089. public async Task Add([FromBody] KnowledgeCorrectionAddDto dto)
  1090. {
  1091. var correction = _mapper.Map<KnowledgeCorrection>(dto);
  1092. await _knowledgeCorrectionRepository.AddAsync(correction, HttpContext.RequestAborted);
  1093. }
  1094. /// <summary>
  1095. /// 删除知识纠错
  1096. /// </summary>
  1097. /// <param name="dto"></param>
  1098. /// <returns></returns>
  1099. //[HttpDelete("knowledge_correction")]
  1100. //public async Task Delete([FromBody] KnowledgeCorrectionDeleteDto dto)
  1101. //{
  1102. // await _knowledgeCorrectionRepository.RemoveAsync(x => x.Id == dto.Id);
  1103. //}
  1104. /// <summary>
  1105. /// 更新知识纠错
  1106. /// </summary>
  1107. /// <param name="dto"></param>
  1108. /// <returns></returns>
  1109. //[HttpPut("knowledge_correction")]
  1110. //public async Task Update([FromBody] KnowledgeCorrectionUpdateDto dto)
  1111. //{
  1112. // var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1113. // if (correction is null)
  1114. // throw UserFriendlyException.SameMessage("无效知识纠错");
  1115. // _mapper.Map(dto, correction);
  1116. // await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  1117. //}
  1118. /// <summary>
  1119. /// 答复知识纠错
  1120. /// </summary>
  1121. /// <param name="dto"></param>
  1122. /// <returns></returns>
  1123. [HttpPut("knowledge_correction/Reply")]
  1124. [LogFilter("答复知识纠错")]
  1125. public async Task Reply([FromBody] KnowledgeCorrectionUpdateDto dto)
  1126. {
  1127. var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1128. if (correction is null)
  1129. throw UserFriendlyException.SameMessage("无效知识纠错");
  1130. _mapper.Map(dto, correction);
  1131. correction.ReplyTime = DateTime.Now;
  1132. correction.ReplyUserName = _sessionContext.UserName;
  1133. correction.State = ECorrectionState.AlreadyAnswered;
  1134. await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  1135. }
  1136. /// <summary>
  1137. /// 获取知识纠错列表
  1138. /// </summary>
  1139. /// <param name="dto"></param>
  1140. /// <returns></returns>
  1141. [HttpGet("knowledge_correction/list")]
  1142. public async Task<PagedDto<KnowledgeCorrectionDto>> List([FromQuery] KnowledgeCorrectionListDto dto)
  1143. {
  1144. var typeSpliceName = string.Empty;
  1145. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  1146. {
  1147. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  1148. typeSpliceName = type?.SpliceName;
  1149. }
  1150. var (total, items) = await _knowledgeCorrectionRepository.Queryable(includeDeleted: true)
  1151. .Includes(x => x.Knowledge)
  1152. .Where(m => m.IsDeleted == false && m.Knowledge.IsDeleted == false)
  1153. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  1154. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  1155. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.Knowledge.KnowledgeType, typeSpliceName))
  1156. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.Knowledge.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
  1157. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1158. .OrderByDescending(x => x.CreationTime)
  1159. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1160. return new PagedDto<KnowledgeCorrectionDto>(total, _mapper.Map<IReadOnlyList<KnowledgeCorrectionDto>>(items));
  1161. }
  1162. /// <summary>
  1163. /// 获取知识库纠错
  1164. /// </summary>
  1165. /// <param name="id"></param>
  1166. /// <returns></returns>
  1167. [HttpGet("knowledge_correction/{id}")]
  1168. public async Task<KnowledgeCorrection> CorrectionEntity(string id)
  1169. {
  1170. return await _knowledgeCorrectionRepository.Queryable()
  1171. .Includes(x => x.Knowledge)
  1172. .FirstAsync(x => x.Id == id);
  1173. }
  1174. #endregion
  1175. #region 知识提问
  1176. /// <summary>
  1177. /// 新增知识提问
  1178. /// </summary>
  1179. /// <param name="dtos"></param>
  1180. /// <returns></returns>
  1181. [HttpPost("knowledge_questions")]
  1182. [LogFilter("新增知识提问")]
  1183. public async Task Add([FromBody] KnowledgeQuestionsAddDto dto)
  1184. {
  1185. var questions = _mapper.Map<KnowledgeQuestions>(dto);
  1186. await _knowledgeQuestionsRepository.AddAsync(questions, HttpContext.RequestAborted);
  1187. }
  1188. /// <summary>
  1189. /// 删除知识提问
  1190. /// </summary>
  1191. /// <param name="dto"></param>
  1192. /// <returns></returns>
  1193. //[HttpDelete("knowledge_questions")]
  1194. //public async Task Delete([FromBody] KnowledgeQuestionsDeleteDto dto)
  1195. //{
  1196. // await _knowledgeQuestionsRepository.RemoveAsync(x => x.Id == dto.Id);
  1197. //}
  1198. /// <summary>
  1199. /// 更新知识提问
  1200. /// </summary>
  1201. /// <param name="dto"></param>
  1202. /// <returns></returns>
  1203. //[HttpPut("knowledge_questions")]
  1204. //public async Task Update([FromBody] KnowledgeQuestionsUpdateDto dto)
  1205. //{
  1206. // var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1207. // if (questions is null)
  1208. // throw UserFriendlyException.SameMessage("无效知识提问");
  1209. // _mapper.Map(dto, questions);
  1210. // await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  1211. //}
  1212. /// <summary>
  1213. /// 答复知识提问
  1214. /// </summary>
  1215. /// <param name="dto"></param>
  1216. /// <returns></returns>
  1217. [HttpPut("knowledge_questions/Reply")]
  1218. [LogFilter("答复知识提问")]
  1219. public async Task Reply([FromBody] KnowledgeQuestionsUpdateDto dto)
  1220. {
  1221. var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1222. if (questions is null)
  1223. throw UserFriendlyException.SameMessage("无效知识提问");
  1224. _mapper.Map(dto, questions);
  1225. questions.ReplyTime = DateTime.Now;
  1226. questions.ReplyUserName = _sessionContext.UserName;
  1227. questions.State = ECorrectionState.AlreadyAnswered;
  1228. await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  1229. }
  1230. /// <summary>
  1231. /// 获取知识提问列表
  1232. /// </summary>
  1233. /// <param name="dto"></param>
  1234. /// <returns></returns>
  1235. [HttpGet("knowledge_questions/list")]
  1236. public async Task<PagedDto<KnowledgeQuestionsDto>> List([FromQuery] KnowledgeQuestionsListDto dto)
  1237. {
  1238. var typeSpliceName = string.Empty;
  1239. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  1240. {
  1241. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  1242. typeSpliceName = type?.SpliceName;
  1243. }
  1244. var (total, items) = await _knowledgeQuestionsRepository.Queryable()
  1245. .Includes(x => x.Knowledge)
  1246. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  1247. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.Knowledge.KnowledgeType, typeSpliceName))
  1248. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.Knowledge.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
  1249. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  1250. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1251. .OrderByDescending(x => x.CreationTime)
  1252. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1253. return new PagedDto<KnowledgeQuestionsDto>(total, _mapper.Map<IReadOnlyList<KnowledgeQuestionsDto>>(items));
  1254. }
  1255. /// <summary>
  1256. /// 获取知识提问
  1257. /// </summary>
  1258. /// <param name="id"></param>
  1259. /// <returns></returns>
  1260. [HttpGet("knowledge_questions/{id}")]
  1261. public async Task<KnowledgeQuestions> QuestionsEntity(string id)
  1262. {
  1263. return await _knowledgeQuestionsRepository.Queryable()
  1264. .Includes(x => x.Knowledge)
  1265. .FirstAsync(x => x.Id == id);
  1266. }
  1267. #endregion
  1268. #region 知识收藏
  1269. /// <summary>
  1270. /// 知识收藏列表
  1271. /// </summary>
  1272. /// <param name="dto"></param>
  1273. /// <returns></returns>
  1274. [HttpGet("knowledge_collect/list")]
  1275. public async Task<PagedDto<KnowledgeCollectDto>> List([FromQuery] KnowledgeCollectListDto dto)
  1276. {
  1277. var (total, items) = await _knowledgeCollectRepository.Queryable()
  1278. .Includes(x => x.Knowledge)
  1279. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Knowledge.Title.Contains(dto.Keyword!) || (x.Knowledge.Summary != null && x.Knowledge.Summary.Contains(dto.Keyword!)))
  1280. .WhereIF(dto.KnowledgeCollectGroupId.NotNullOrEmpty(), x => x.KnowledgeCollectGroupId == dto.KnowledgeCollectGroupId)
  1281. .Where(x => x.CreatorId == _sessionContext.UserId)
  1282. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1283. .Where(x => x.Collect!.Value)
  1284. .OrderByDescending(x => x.CreationTime)
  1285. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1286. return new PagedDto<KnowledgeCollectDto>(total, _mapper.Map<IReadOnlyList<KnowledgeCollectDto>>(items));
  1287. }
  1288. /// <summary>
  1289. /// 新增知识收藏
  1290. /// </summary>
  1291. /// <param name="dtos"></param>
  1292. /// <returns></returns>
  1293. [HttpPost("knowledge_collect")]
  1294. [LogFilter("知识收藏")]
  1295. public async Task Add([FromBody] KnowledgeCollectAddDto dto)
  1296. {
  1297. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1298. if (collect != null)
  1299. {
  1300. collect.Collect = dto.Collect;
  1301. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1302. }
  1303. else
  1304. {
  1305. var collectNew = _mapper.Map<KnowledgeCollect>(dto);
  1306. await _knowledgeCollectRepository.AddAsync(collectNew, HttpContext.RequestAborted);
  1307. }
  1308. var count = await _knowledgeCollectRepository.Queryable()
  1309. .Where(m => m.KnowledgeId == dto.KnowledgeId && m.Collect == true).CountAsync();
  1310. await _knowledgeRepository.Updateable()
  1311. .Where(m => m.Id == dto.KnowledgeId)
  1312. .SetColumns(m => m.CollectCount == count)
  1313. .ExecuteCommandAsync();
  1314. }
  1315. /// <summary>
  1316. /// 知识评分
  1317. /// </summary>
  1318. /// <param name="dto"></param>
  1319. /// <returns></returns>
  1320. [HttpDelete("knowledge_score")]
  1321. [LogFilter("知识评分")]
  1322. public async Task Delete([FromBody] KnowledgeCollectAddDto dto)
  1323. {
  1324. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1325. if (collect != null)
  1326. {
  1327. if (collect.Score > 0)
  1328. throw UserFriendlyException.SameMessage("当前知识已经评分");
  1329. collect.Score = dto.Score;
  1330. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1331. }
  1332. else
  1333. {
  1334. var questions = _mapper.Map<KnowledgeCollect>(dto);
  1335. await _knowledgeCollectRepository.AddAsync(questions, HttpContext.RequestAborted);
  1336. }
  1337. //计算总分
  1338. var sugar = _knowledgeCollectRepository.Queryable().Where(x => x.KnowledgeId == dto.KnowledgeId);
  1339. var count = await sugar.CountAsync();
  1340. var collects = await sugar.SumAsync(x => x.Score);
  1341. var score = collects / count;
  1342. var knowledge = await _knowledgeRepository.GetAsync(x => x.Id == dto.KnowledgeId);
  1343. if (knowledge != null)
  1344. {
  1345. knowledge.Score = decimal.Round(score.Value, 1);
  1346. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  1347. }
  1348. }
  1349. #endregion
  1350. #region 知识评论
  1351. /// <summary>
  1352. /// 新增知识评论
  1353. /// </summary>
  1354. /// <param name="dto"></param>
  1355. /// <returns></returns>
  1356. [HttpPost("knowledge_comment")]
  1357. public async Task Add([FromBody] KnowledgeCommentAddDto dto)
  1358. {
  1359. var model = _mapper.Map<KnowledgeComment>(dto);
  1360. await _knowledgeCommentRepository.AddAsync(model, HttpContext.RequestAborted);
  1361. if (!string.IsNullOrEmpty(dto.ReplyId))
  1362. {
  1363. var comment = await _knowledgeCommentRepository.GetAsync(dto.ReplyId);
  1364. if (comment != null)
  1365. {
  1366. comment.ReplyNum++;
  1367. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1368. }
  1369. }
  1370. }
  1371. /// <summary>
  1372. /// 删除知识评论
  1373. /// </summary>
  1374. /// <param name="dto"></param>
  1375. /// <returns></returns>
  1376. [HttpDelete("knowledge_comment")]
  1377. public async Task Delete([FromBody] KnowledgeCommentDeleteDto dto)
  1378. {
  1379. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1380. if (comment is null)
  1381. throw UserFriendlyException.SameMessage("无效评论");
  1382. if (comment.CreatorId != _sessionContext.UserId)
  1383. throw UserFriendlyException.SameMessage("只有评论者可以删除当前评论");
  1384. await _knowledgeCommentRepository.RemoveAsync(x => x.Id == dto.Id);
  1385. }
  1386. /// <summary>
  1387. /// 修改知识评论
  1388. /// </summary>
  1389. /// <param name="dto"></param>
  1390. /// <returns></returns>
  1391. [HttpPut("knowledge_comment")]
  1392. public async Task Update([FromBody] KnowledgeCommentUpdateDto dto)
  1393. {
  1394. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1395. if (comment is null)
  1396. throw UserFriendlyException.SameMessage("无效评论");
  1397. _mapper.Map(dto, comment);
  1398. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1399. }
  1400. /// <summary>
  1401. /// 知识评论列表
  1402. /// </summary>
  1403. /// <param name="dto"></param>
  1404. /// <returns></returns>
  1405. [HttpGet("knowledge_comment/list")]
  1406. public async Task<List<KnowledgeCommentDto>> List([FromQuery] KnowledgeCommentListDto dto)
  1407. {
  1408. var comments = await _knowledgeCommentRepository.Queryable()
  1409. .WhereIF(!string.IsNullOrEmpty(dto.KnowledgeId), x => x.KnowledgeId == dto.KnowledgeId)
  1410. .WhereIF(!string.IsNullOrEmpty(dto.ReplyId), x => x.ReplyId == dto.ReplyId)
  1411. .WhereIF(dto.All.HasValue && dto.All == false, x => x.CreatorId == _sessionContext.UserId)
  1412. .OrderByDescending(x => x.CreationTime)
  1413. .ToListAsync();
  1414. return new List<KnowledgeCommentDto>(_mapper.Map<IReadOnlyList<KnowledgeCommentDto>>(comments));
  1415. }
  1416. #endregion
  1417. #region 收藏分组
  1418. /// <summary>
  1419. /// 增加收藏分组
  1420. /// </summary>
  1421. [HttpPost("group")]
  1422. public async Task<KnowledgeCollectGroupOutDto> SaveKnowledgeCoolectGroupAsync([FromBody] KnowledgeCollectGroupInDto dto)
  1423. {
  1424. var entity = dto.Adapt<KnowledgeCollectGroup>();
  1425. if (await _knowledgeCollectGroupRepository
  1426. .Queryable()
  1427. .Where(m => m.Name == dto.Name && m.CreatorId == _sessionContext.UserId)
  1428. .AnyAsync() == true) throw UserFriendlyException.SameMessage("分组名重复, 请重新输入!");
  1429. var key = await _knowledgeCollectGroupRepository.AddAsync(entity);
  1430. if (key.IsNullOrEmpty()) throw UserFriendlyException.SameMessage("添加失败, 请重试");
  1431. var outDto = dto.Adapt<KnowledgeCollectGroupOutDto>();
  1432. outDto.Id = key;
  1433. return outDto;
  1434. }
  1435. /// <summary>
  1436. /// 删除收藏分组
  1437. /// </summary>
  1438. [HttpDelete("group")]
  1439. public async Task DeleteKnowledgeCoolectGroupAsync([FromQuery] string id)
  1440. {
  1441. var entity = await _knowledgeCollectGroupRepository.Queryable()
  1442. .Where(m => m.Id == id && m.CreatorId == _sessionContext.UserId)
  1443. .FirstAsync() ?? throw new UserFriendlyException("数据不存在");
  1444. entity.IsDeleted = true;
  1445. await _knowledgeCollectGroupRepository.UpdateAsync(entity);
  1446. await _knowledgeCollectRepository.Updateable()
  1447. .Where(m => m.KnowledgeCollectGroupId == id && m.CreatorId == _sessionContext.UserId)
  1448. .SetColumns(m => m.IsDeleted == true)
  1449. .ExecuteCommandAsync();
  1450. }
  1451. /// <summary>
  1452. /// 获取分组收藏列表
  1453. /// </summary>
  1454. /// <returns></returns>
  1455. [HttpGet("group")]
  1456. public async Task<PagedDto<KnowledgeCollectGroupOutDto>> GetKnowledgeCollectGroupListAsync([FromQuery] KnowledgeCollectGroupListInDto dto)
  1457. {
  1458. return (await _knowledgeCollectGroupRepository.Queryable()
  1459. .WhereIF(dto.Keyword.NotNullOrEmpty(), m => m.Name.Contains(dto.Keyword))
  1460. .Where(m => m.CreatorId == _sessionContext.UserId)
  1461. .Select<KnowledgeCollectGroupOutDto>()
  1462. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted)
  1463. ).ToPaged();
  1464. }
  1465. #endregion
  1466. #region PageView 浏览记录
  1467. /// <summary>
  1468. /// 浏览记录集合
  1469. /// </summary>
  1470. /// <param name="dto"></param>
  1471. /// <returns></returns>
  1472. [HttpGet("pageview")]
  1473. public async Task<PagedDto<PageViewOutDto>> GetPageViewListAsync([FromQuery] PageViewInDto dto)
  1474. {
  1475. return (await _knowApplication.GetPageViewListAsync(dto, HttpContext.RequestAborted))
  1476. .ToPaged();
  1477. }
  1478. /// <summary>
  1479. /// 浏览记录集合-导出
  1480. /// </summary>
  1481. /// <param name="dto"></param>
  1482. /// <returns></returns>
  1483. [HttpPost("pageview/export")]
  1484. public async Task<FileStreamResult> GetPageViewListAsync([FromBody] ExportExcelDto<PageViewInDto> dto)
  1485. {
  1486. var items = (await _knowApplication.GetPageViewListAsync(dto.QueryDto, HttpContext.RequestAborted))
  1487. .Item2;
  1488. return _exportApplication.GetExcelFile(dto, items, "浏览记录");
  1489. }
  1490. #endregion
  1491. #region 热词
  1492. /// <summary>
  1493. /// 新增热词
  1494. /// </summary>
  1495. /// <param name="dto"></param>
  1496. /// <returns></returns>
  1497. [HttpPost("hotword")]
  1498. public async Task AddKnowledgeHotWordAsync([FromBody] AddKnowledgeHotWordInDto dto)
  1499. {
  1500. await _knowApplication.AddKnowledgeHotWordAsync(dto, HttpContext.RequestAborted);
  1501. }
  1502. /// <summary>
  1503. /// 新增热词页面基础数据
  1504. /// </summary>
  1505. /// <param name="dto"></param>
  1506. /// <returns></returns>
  1507. [HttpGet("hotword/basedata")]
  1508. public Dictionary<string, dynamic> AddKnowledgeHotWordBaseDataAsync()
  1509. {
  1510. //return _baseDataApplication
  1511. // .KnowledgeHotWordType()
  1512. // .Build();
  1513. return new Dictionary<string, dynamic>
  1514. {
  1515. { "knowledgeHotWordType", EnumExts.GetDescriptions<EKnowledgeHotWordType>() }
  1516. };
  1517. }
  1518. /// <summary>
  1519. /// 热词集合
  1520. /// </summary>
  1521. /// <param name="dto"></param>
  1522. /// <returns></returns>
  1523. [HttpGet("hotword")]
  1524. public async Task<PagedDto<KnowledgeHotWordOutDto>> GetKnowledgeHotWordListAsync([FromQuery] KnowledgeHotWordInDto dto)
  1525. {
  1526. return (await _knowApplication.GetKnowledgeHotWordListAsync(dto, HttpContext.RequestAborted))
  1527. .ToPaged();
  1528. }
  1529. /// <summary>
  1530. /// 修改热词
  1531. /// </summary>
  1532. /// <param name="dto"></param>
  1533. /// <returns></returns>
  1534. [HttpPut("hotword")]
  1535. public async Task UpdateKnowledgeHotWordAsync([FromBody] UpdateKnowledgeHotWordInDto dto)
  1536. {
  1537. await _knowApplication.UpdateKnowledgeHotWordAsync(dto, HttpContext.RequestAborted);
  1538. }
  1539. /// <summary>
  1540. /// 删除热词
  1541. /// </summary>
  1542. /// <param name="id"></param>
  1543. /// <returns></returns>
  1544. [HttpDelete("hotword")]
  1545. public async Task DeleteKnowledgeHotWordAsync([FromQuery] string id)
  1546. {
  1547. await _knowledgeHotWordRepository
  1548. .RemoveAsync(id);
  1549. }
  1550. #endregion
  1551. #region 知识审批
  1552. #endregion
  1553. }
  1554. }