KnowledgeController.cs 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151
  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 Hotline.Share.Requests;
  37. using Microsoft.Extensions.Options;
  38. using XF.Domain.Authentications;
  39. using XF.Domain.Exceptions;
  40. using XF.Domain.Repository;
  41. using XF.Utility.EnumExtensions;
  42. using System.Threading;
  43. using Hotline.Caching.Interfaces;
  44. using Hotline.Import;
  45. using Hotline.Caching.Services;
  46. using Hotline.Share.Enums.Order;
  47. using MiniExcelLibs;
  48. namespace Hotline.Api.Controllers
  49. {
  50. public class KnowledgeController : BaseController
  51. {
  52. #region 注入
  53. private readonly IExportApplication _exportApplication;
  54. private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
  55. private readonly IRepository<KnowledgeApprove> _knowledgeApproRepository;
  56. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  57. private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
  58. private readonly IWordHelperService _wordHelperService;
  59. private readonly BaseDataApplication _baseDataApplication;
  60. private readonly IKnowledgeRepository _knowledgeRepository;
  61. private readonly ISessionContext _sessionContext;
  62. private readonly IKnowledgeDomainService _knowledgeDomainService;
  63. private readonly IMapper _mapper;
  64. private readonly IKnowApplication _knowApplication;
  65. private readonly IMediator _mediator;
  66. private readonly IWorkflowApplication _workflowApplication;
  67. private readonly IWorkflowDomainService _workflowDomainService;
  68. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  69. private readonly IRepository<User> _userRepository;
  70. private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
  71. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  72. private readonly IRepositoryTextSearch<KnowledgeTs> _repositoryts;
  73. private readonly IRepository<KnowledgeWord> _knowledgeWrodRepository;
  74. private readonly IRepository<KnowledgeQuestions> _knowledgeQuestionsRepository;
  75. private readonly IRepository<KnowledgeCorrection> _knowledgeCorrectionRepository;
  76. private readonly IRepository<KnowledgeCollect> _knowledgeCollectRepository;
  77. private readonly ISystemDomainService _systemDomainService;
  78. private readonly IRepository<KnowledgeComment> _knowledgeCommentRepository;
  79. private readonly ISystemOrganizeRepository _systemOrganizeRepository;
  80. private readonly IFileRepository _fileRepository;
  81. private readonly ICapPublisher _capPublisher;
  82. private readonly IBulletinApplication _bulletinApplication;
  83. private readonly IRepository<KnowledgeCollectGroup> _knowledgeCollectGroupRepository;
  84. private readonly IRepository<KnowledgePv> _knowledgePvepository;
  85. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  86. public KnowledgeController(
  87. IKnowledgeRepository knowledgeRepository,
  88. ISessionContext sessionContext,
  89. IKnowledgeDomainService knowledgeDomainService,
  90. IMapper mapper,
  91. IKnowApplication knowApplication,
  92. IMediator mediator,
  93. IWorkflowApplication workflowApplication,
  94. IWorkflowDomainService workflowDomainService,
  95. IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
  96. IRepository<User> userRepository,
  97. IRepository<KnowledgeType> knowledgeTypeRepository,
  98. IRepository<Hotspot> hotspotTypeRepository,
  99. IRepositoryTextSearch<KnowledgeTs> repositoryts,
  100. IRepository<KnowledgeWord> knowledgeWrodRepository,
  101. IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
  102. IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
  103. IRepository<KnowledgeCollect> knowledgeCollectRepository,
  104. ISystemDomainService systemDomainService,
  105. IRepository<KnowledgeComment> knowledgeCommentRepository,
  106. ISystemOrganizeRepository systemOrganizeRepository,
  107. IFileRepository fileRepository,
  108. ICapPublisher capPublisher,
  109. IBulletinApplication bulletinApplication,
  110. IRepository<KnowledgeCollectGroup> knowledgeCollectGroupRepository,
  111. IExportApplication exportApplication,
  112. BaseDataApplication baseDataApplication,
  113. IWordHelperService wordHelperService,
  114. IRepository<KnowledgePv> knowledgePvepository,
  115. IRepository<KnowledgeWord> knowledgeWordRepository,
  116. IRepository<KnowledgeHotWord> knowledgeWordHotRepository,
  117. IOptionsSnapshot<AppConfiguration> appOptions,
  118. IRepository<KnowledgeHotWord> knowledgeHotWordRepository,
  119. IRepository<KnowledgeApprove> knowledgeApproRepository,
  120. ISystemSettingCacheManager _systemSettingCacheManager)
  121. {
  122. _knowledgeRepository = knowledgeRepository;
  123. _sessionContext = sessionContext;
  124. _knowledgeDomainService = knowledgeDomainService;
  125. _mapper = mapper;
  126. _knowApplication = knowApplication;
  127. _mediator = mediator;
  128. _workflowApplication = workflowApplication;
  129. _workflowDomainService = workflowDomainService;
  130. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  131. _userRepository = userRepository;
  132. _knowledgeTypeRepository = knowledgeTypeRepository;
  133. _hotspotTypeRepository = hotspotTypeRepository;
  134. _repositoryts = repositoryts;
  135. _knowledgeWrodRepository = knowledgeWrodRepository;
  136. _knowledgeQuestionsRepository = knowledgeQuestionsRepository;
  137. _knowledgeCorrectionRepository = knowledgeCorrectionRepository;
  138. _knowledgeCollectRepository = knowledgeCollectRepository;
  139. _systemDomainService = systemDomainService;
  140. _knowledgeCommentRepository = knowledgeCommentRepository;
  141. _systemOrganizeRepository = systemOrganizeRepository;
  142. _fileRepository = fileRepository;
  143. _capPublisher = capPublisher;
  144. _bulletinApplication = bulletinApplication;
  145. _knowledgeCollectGroupRepository = knowledgeCollectGroupRepository;
  146. _exportApplication = exportApplication;
  147. _baseDataApplication = baseDataApplication;
  148. _wordHelperService = wordHelperService;
  149. _knowledgePvepository = knowledgePvepository;
  150. _knowledgeWordRepository = knowledgeWordRepository;
  151. _knowledgeHotWordRepository = knowledgeHotWordRepository;
  152. _knowledgeApproRepository = knowledgeApproRepository;
  153. this._systemSettingCacheManager = _systemSettingCacheManager;
  154. _appOptions = appOptions;
  155. }
  156. #endregion
  157. #region 知识管理
  158. /// <summary>
  159. /// 知识库-新增
  160. /// </summary>
  161. /// <param name="dto"></param>
  162. /// <returns></returns>
  163. [HttpPost("add")]
  164. [LogFilter("知识新增")]
  165. public async Task<string> AddKnowledge([FromBody] AddStartFlowDto dto)
  166. {
  167. //var addDto = _mapper.Map<AddKnowledgeDto>(dto.Data);
  168. var kn = _mapper.Map<Knowledge>(dto.Data);
  169. kn.SourceOrganizeId = _sessionContext.RequiredOrgId;
  170. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == kn.Title).AnyAsync();
  171. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  172. //Code为空,从新生成Code
  173. if (string.IsNullOrEmpty(kn.Code))
  174. kn.Code = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
  175. kn.Status = EKnowledgeStatus.Drafts;
  176. kn.InitId();
  177. if (dto.Data.Files.NotNullOrEmpty()) kn.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, kn.Id, "", HttpContext.RequestAborted);
  178. await _knowledgeRepository.AddAsync(kn, HttpContext.RequestAborted);
  179. if (dto.Data.KnowledgeType.Any())
  180. {
  181. List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
  182. types.ForEach(x => x.KnowledgeId = kn.Id);
  183. //await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
  184. }
  185. if (dto.Workflow != null && !string.IsNullOrEmpty(kn.Id))
  186. {
  187. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  188. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  189. startDto.Title = "知识库新增";
  190. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, kn.Id, cancellationToken: HttpContext.RequestAborted);
  191. await StartFlow(kn.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  192. //var knowledge = await _knowledgeRepository.GetAsync(kn.Id);
  193. //knowledge.Status = EKnowledgeStatus.Auditing;
  194. //await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  195. }
  196. return kn.Id;
  197. }
  198. /// <summary>
  199. /// 知识库-新增(new)
  200. /// </summary>
  201. [HttpPost]
  202. public async Task<string> Add([FromBody] AddKnowledgeDto dto)
  203. {
  204. var kn = await _knowledgeDomainService.AddKnowledgeAsync(dto, HttpContext.RequestAborted);
  205. return kn.Id;
  206. }
  207. /// <summary>
  208. /// 知识库-新增并发起审批(new)
  209. /// </summary>
  210. [HttpPost("add-and-approve")]
  211. public async Task<string> AddAndApprove([FromBody] AddKnowledgeDto dto)
  212. {
  213. var kn = await _knowledgeDomainService.AddKnowledgeAsync(dto, HttpContext.RequestAborted);
  214. var approve = await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Add, kn, null,
  215. HttpContext.RequestAborted);
  216. return approve.Id;
  217. }
  218. /// <summary>
  219. /// 知识库-知识下架
  220. /// </summary>
  221. /// <param name="Id"></param>
  222. /// <returns></returns>
  223. [HttpPut("offshelf")]
  224. [LogFilter("知识下架")]
  225. public async Task KnowledgeOffShelf([FromBody] OffShelfStartFlowDto dto)
  226. {
  227. var know = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
  228. if (know != null && know.Status == EKnowledgeStatus.OnShelf)
  229. {
  230. if (_sessionContext.OrgIsCenter || !_appOptions.Value.IsYiBin)
  231. {
  232. know.Status = EKnowledgeStatus.OffShelf;
  233. know.OnShelfTime = null;
  234. know.OffShelfTime = DateTime.Now;
  235. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  236. var pushKnowledge = _mapper.Map<KnowledgeSendDto>(know);
  237. pushKnowledge.CategoryCode = "01";
  238. pushKnowledge.CategoryName = "公共服务";
  239. //推省上
  240. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
  241. }
  242. else
  243. {
  244. know.Status = EKnowledgeStatus.Auditing;
  245. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  246. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  247. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeOffshelf;
  248. startDto.Opinion = dto.Data.Opinion;
  249. startDto.Title = "知识库下架";
  250. await StartFlow(know.Id, WorkflowModuleConsts.KnowledgeOffshelf, EKnowledgeApplyType.Offshelf, startDto);
  251. }
  252. }
  253. else
  254. throw UserFriendlyException.SameMessage("知识下架失败");
  255. }
  256. /// <summary>
  257. /// 知识库-知识下架(new)
  258. /// </summary>
  259. [HttpPost("offshelf")]
  260. [LogFilter("知识下架")]
  261. public Task OffShelf([FromBody] OffShelfKnowledgeDto dto) =>
  262. _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
  263. /// <summary>
  264. /// 知识库-知识下架并发起审批(new)
  265. /// </summary>
  266. [HttpPost("offshelf-and-approve")]
  267. [LogFilter("知识下架并发起审批")]
  268. public async Task OffShelfAndApprove([FromBody] OffShelfKnowledgeDto dto)
  269. {
  270. var kn = await _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
  271. await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.OffShelf,
  272. kn, dto.Opinion, HttpContext.RequestAborted);
  273. }
  274. /// <summary>
  275. /// 知识库-知识上架
  276. /// </summary>
  277. /// <param name="Id"></param>
  278. /// <returns></returns>
  279. [HttpPut("ontheshelf")]
  280. [LogFilter("知识上架")]
  281. public async Task KnowledgeOnTheShelf(string Id)
  282. {
  283. var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  284. if (know != null && know.Status == EKnowledgeStatus.OffShelf)
  285. {
  286. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == know.Title && x.Id != know.Id).AnyAsync();
  287. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  288. if (know.ExpiredTime < DateTime.Now) throw UserFriendlyException.SameMessage("知识已过期不能上架!");
  289. know.Status = EKnowledgeStatus.OnShelf;
  290. know.OnShelfTime = DateTime.Now;
  291. know.OffShelfTime = null;
  292. await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
  293. }
  294. else
  295. throw UserFriendlyException.SameMessage("知识上架失败");
  296. }
  297. /// <summary>
  298. /// 知识库-标题
  299. /// </summary>
  300. /// <param name="title"></param>
  301. /// <returns></returns>
  302. [HttpGet("title")]
  303. public async Task<bool> KnowledgeTitle([FromQuery] KnowledgeTitleDto dto)
  304. {
  305. var count = await _knowledgeRepository.Queryable()
  306. .WhereIF(!string.IsNullOrEmpty(dto.Id), x => x.Id != dto.Id)
  307. .Where(x => x.Title == dto.Title && x.Status == EKnowledgeStatus.OnShelf).CountAsync();
  308. return count > 0;
  309. }
  310. /// <summary>
  311. /// 知识库-修改
  312. /// </summary>
  313. /// <param name="dto"></param>
  314. /// <returns></returns>
  315. [HttpPut("update")]
  316. [LogFilter("知识修改")]
  317. public async Task UpdateKnowledge([FromBody] UpdateStartFlowDto dto)
  318. {
  319. var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id);
  320. if (knowledge == null)
  321. throw UserFriendlyException.SameMessage("知识库数据错误");
  322. if ((knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing) && (knowledge.ExpiredTime.HasValue && knowledge.ExpiredTime.Value > DateTime.Now))
  323. throw UserFriendlyException.SameMessage("知识库数据不可修改");
  324. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.OnShelf && x.Title == dto.Data.Title && x.Id != dto.Data.Id).AnyAsync();
  325. if (any) throw UserFriendlyException.SameMessage("当前知识标题存在重复标题!");
  326. _mapper.Map(dto.Data, knowledge);
  327. knowledge.HotspotId = dto.Data.HotspotId;
  328. knowledge.HotspotExternal = dto.Data.HotspotExternal;
  329. if (dto.Data.Files.Any())
  330. knowledge.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, knowledge.Id, "", HttpContext.RequestAborted);
  331. else
  332. knowledge.FileJson = new List<Share.Dtos.File.FileJson>();
  333. if (dto.Workflow != null) knowledge.Renewaln = knowledge.Status != EKnowledgeStatus.Drafts;
  334. if (_appOptions.Value.IsYiBin)
  335. {
  336. //临时处理 修改后提交修改基本信息
  337. if (!_sessionContext.OrgIsCenter)
  338. {
  339. knowledge.Attribution = "部门知识库";
  340. }
  341. knowledge.CreatorId = _sessionContext.UserId;
  342. knowledge.CreatorName = _sessionContext.UserName;
  343. knowledge.CreatorOrgId = _sessionContext.OrgId;
  344. knowledge.CreatorOrgName = _sessionContext.OrgName;
  345. knowledge.CreatorOrgLevel = _sessionContext.OrgLevel;
  346. }
  347. await _knowledgeRepository.UpdateNullAsync(knowledge, HttpContext.RequestAborted);
  348. if (dto.Data.KnowledgeType.Any())
  349. {
  350. //var anyRelationTypes = await _knowledgeRelationTypeRepository.Queryable().Where(x => x.KnowledgeId == knowledge.Id).ToListAsync();
  351. //if (anyRelationTypes.Any())
  352. // await _knowledgeRelationTypeRepository.RemoveRangeAsync(anyRelationTypes);
  353. //List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
  354. //types.ForEach(x => x.KnowledgeId = dto.Data.Id);
  355. //await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
  356. }
  357. if (dto.Workflow != null)
  358. {
  359. if (knowledge.Status == EKnowledgeStatus.Drafts)
  360. {
  361. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  362. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeAdd;
  363. startDto.Title = "知识库新增";
  364. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  365. await StartFlow(knowledge.Id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, startDto);
  366. }
  367. else
  368. {
  369. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  370. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeUpdate;
  371. startDto.Title = "知识库修改";
  372. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  373. await StartFlow(knowledge.Id, WorkflowModuleConsts.KnowledgeUpdate, EKnowledgeApplyType.Update, startDto);
  374. }
  375. }
  376. }
  377. /// <summary>
  378. /// 知识库-修改(new)
  379. /// </summary>
  380. /// <param name="dto"></param>
  381. /// <returns></returns>
  382. [HttpPut]
  383. [LogFilter("知识修改")]
  384. public Task Update([FromBody] UpdateKnowledgeDto dto) =>
  385. _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
  386. /// <summary>
  387. /// 知识库-修改(new)
  388. /// </summary>
  389. /// <param name="dto"></param>
  390. /// <returns></returns>
  391. [HttpPut("update-and-approve")]
  392. [LogFilter("知识修改")]
  393. public async Task UpdateAndApprove([FromBody] UpdateKnowledgeAndApproveDto dto)
  394. {
  395. var kn = await _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
  396. var exists = await _knowledgeApproRepository.Queryable()
  397. .AnyAsync(d => d.KnowledgeId == dto.Id && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle,
  398. HttpContext.RequestAborted);
  399. if (exists)
  400. throw new UserFriendlyException($"该知识存在待审批申请, knId: {dto.Id}", "该知识存在待审批申请, 请先审批");
  401. if (kn.Status == EKnowledgeStatus.Drafts)
  402. {
  403. await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Add, kn, null,
  404. HttpContext.RequestAborted);
  405. }
  406. else
  407. {
  408. await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Update, kn, dto.Opinion,
  409. HttpContext.RequestAborted);
  410. }
  411. }
  412. /// <summary>
  413. /// 批量更新公开状态(new)
  414. /// </summary>
  415. /// <returns></returns>
  416. [HttpPost("publish-batch")]
  417. public async Task PublishBatch([FromBody] PublishBatchRequest request)
  418. {
  419. var kns = request.KnowledgeIds.Select(d => new Knowledge
  420. {
  421. Id = d,
  422. IsPublic = request.IsPublic
  423. }).ToList();
  424. await _knowledgeRepository.Updateable(kns)
  425. .UpdateColumns(d => d.IsPublic)
  426. .ExecuteCommandAsync(HttpContext.RequestAborted);
  427. }
  428. /// <summary>
  429. /// 批量审核
  430. /// </summary>
  431. /// <returns></returns>
  432. [HttpPost("batch_audit")]
  433. public async Task<string> KnowledgeBatchAuditAsync([FromBody] KnowledgeBatchAuditInDto dto)
  434. {
  435. var result = new StringBuilder();
  436. var fail = 0;
  437. var success = 0;
  438. var nextWorkflowDto = new NextWorkflowDto
  439. {
  440. IsSms = dto.IsSms,
  441. ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed,
  442. Opinion = dto.Opinion
  443. };
  444. foreach (var knowledgeId in dto.KnowledgeIds)
  445. {
  446. try
  447. {
  448. var knowledge = await _knowledgeDomainService.KnowledgeInfo(knowledgeId, HttpContext.RequestAborted);
  449. nextWorkflowDto.WorkflowId = knowledge.WorkflowId;
  450. NextStepsWithOpinionDto<NextStepOption> next = null;
  451. try
  452. {
  453. next = await _workflowApplication.GetNextStepsAsync(knowledge.WorkflowId, HttpContext.RequestAborted);
  454. }
  455. catch (UserFriendlyException e)
  456. {
  457. if (e.Message.Contains("未找到对应节点"))
  458. {
  459. result.Append("无权审核:" + knowledge.Title);
  460. fail++;
  461. }
  462. else
  463. {
  464. throw;
  465. }
  466. }
  467. if (next == null) continue;
  468. nextWorkflowDto.StepId = next.StepId;
  469. nextWorkflowDto.NextStepCode = next.Steps.First().Key;
  470. nextWorkflowDto.NextStepName = next.Steps.First().Value;
  471. if (dto.IsPass)
  472. await _workflowDomainService.NextAsync(_sessionContext, nextWorkflowDto,
  473. cancellationToken: HttpContext.RequestAborted);
  474. else
  475. {
  476. var reject = nextWorkflowDto.Adapt<RejectDto>();
  477. await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
  478. }
  479. success++;
  480. }
  481. catch (UserFriendlyException e)
  482. {
  483. result.Append(e.Message);
  484. fail++;
  485. }
  486. }
  487. return $"总共: {dto.KnowledgeIds.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
  488. }
  489. /// <summary>
  490. /// 根据知识标题自动分词并保存到关键词表中
  491. /// </summary>
  492. /// <param name="title"></param>
  493. /// <returns></returns>
  494. [HttpGet("participle")]
  495. public async Task<IList<KnowledgeWordOutDto>> KnowledgeKeyWord([FromQuery] string title)
  496. {
  497. return await _knowApplication.TitleParticiple(title);
  498. }
  499. /// <summary>
  500. /// 删除知识
  501. /// </summary>
  502. /// <param name="id"></param>
  503. /// <returns></returns>
  504. [HttpDelete]
  505. [LogFilter("删除知识")]
  506. public async Task Remove([FromBody] DeleteStartFlowDto dto)
  507. {
  508. //var delete = _mapper.Map<KnowledgeDto>(dto.Data);
  509. var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
  510. if (knowledge == null)
  511. throw UserFriendlyException.SameMessage("无效知识库数据");
  512. if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
  513. throw UserFriendlyException.SameMessage("知识库数据不可删除");
  514. if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
  515. {
  516. await _knowledgeRepository.RemoveAsync(knowledge, false, HttpContext.RequestAborted);
  517. }
  518. else
  519. {
  520. var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
  521. startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeDelete;
  522. startDto.Title = "知识库删除";
  523. //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
  524. await StartFlow(dto.Data.Id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, startDto);
  525. }
  526. }
  527. /// <summary>
  528. /// 删除知识(new)
  529. /// </summary>
  530. [HttpDelete("remove")]
  531. [LogFilter("删除知识")]
  532. public async Task Remove([FromBody] DeleteKnowledgeDto dto)
  533. {
  534. var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  535. if (knowledge == null)
  536. throw UserFriendlyException.SameMessage("无效知识库数据");
  537. if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
  538. throw UserFriendlyException.SameMessage("知识库数据不可删除");
  539. if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
  540. {
  541. await _knowledgeRepository.RemoveAsync(knowledge, false, HttpContext.RequestAborted);
  542. }
  543. else
  544. {
  545. var exists = await _knowledgeApproRepository.Queryable()
  546. .AnyAsync(d => d.KnowledgeId == dto.Id && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle,
  547. HttpContext.RequestAborted);
  548. if (exists)
  549. throw new UserFriendlyException($"该知识存在待审批申请, knId: {dto.Id}", "该知识存在待审批申请, 请先审批");
  550. await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Delete, knowledge, dto.Opinion,
  551. HttpContext.RequestAborted);
  552. }
  553. }
  554. /// <summary>
  555. /// 增加搜索量
  556. /// </summary>
  557. /// <param name="dto"></param>
  558. /// <returns></returns>
  559. [HttpPost("search_num")]
  560. [LogFilter("知识搜索")]
  561. public async Task SearchNum([FromBody] KnowledgeSearchNumDto dto)
  562. {
  563. var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  564. if (knowledge == null)
  565. throw UserFriendlyException.SameMessage("无效知识库数据");
  566. knowledge.SearchNum++;
  567. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  568. }
  569. /// <summary>
  570. /// 搜索量列表
  571. /// </summary>
  572. /// <param name="dto"></param>
  573. /// <returns></returns>
  574. [HttpGet("search_num/list")]
  575. public async Task<PagedDto<KnowledgeDto>> SearchNumList([FromQuery] KnowledgeCollectListDto dto)
  576. {
  577. var query = _knowledgeRepository.Queryable()
  578. .Where(x => x.Status == EKnowledgeStatus.OnShelf)
  579. .Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  580. .OrderByDescending(x => x.SearchNum);
  581. if (_sessionContext.OrgIsCenter == false)
  582. {
  583. query = query.Where(m => m.KnowledgeTypes.Any(a => a.IsDeleted == false && a.Orgs
  584. .Any(k => k.Id.StartsWith(_sessionContext.RequiredOrgId))));
  585. query = query.Where(m => m.Attribution == "部门知识库");
  586. }
  587. var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  588. return new PagedDto<KnowledgeDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDto>>(items));
  589. }
  590. /// <summary>
  591. /// 知识库-知识修改-查询详情
  592. /// </summary>
  593. /// <param name="Id"></param>
  594. /// <returns></returns>
  595. [Obsolete("请调用info/{Id}")]
  596. [HttpGet("updateinfo/{Id}")]
  597. public async Task<KnowledgeInfoDto> KnowledgeUpdateInfo(string Id)
  598. {
  599. //var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
  600. var know = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
  601. if (know is null)
  602. throw UserFriendlyException.SameMessage("知识查询失败!");
  603. var knowledgeInfoDto = _mapper.Map<KnowledgeInfoDto>(know);
  604. if (knowledgeInfoDto != null && !string.IsNullOrEmpty(knowledgeInfoDto.Content))
  605. knowledgeInfoDto.Content = _bulletinApplication.GetSiteUrls(knowledgeInfoDto.Content);
  606. //分类
  607. //var type = await _knowledgeTypeRepository.GetAsync(know.KnowledgeTypeId, HttpContext.RequestAborted);
  608. //if (type != null)
  609. // knowledgeInfoDto.KnowledgeTypeName = type.SpliceName;
  610. //热点
  611. var hot = await _hotspotTypeRepository.GetAsync(know.HotspotId, HttpContext.RequestAborted);
  612. if (hot != null)
  613. knowledgeInfoDto.HotspotName = hot.HotSpotFullName;
  614. //收藏
  615. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  616. if (collect != null)
  617. knowledgeInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  618. return knowledgeInfoDto;
  619. }
  620. /// <summary>
  621. /// 知识库-查询详情-增加浏览量
  622. /// </summary>
  623. /// <param name="Id">知识Id</param>
  624. /// <param name="IsAddPv">默认不增加,false不增加,true增加浏览量</param>
  625. /// <returns></returns>
  626. [HttpGet("info/{Id}")]
  627. public async Task<KnowledgeDto> KnowledgeInfo(string Id, bool? IsAddPv)
  628. {
  629. var knowledge = await _knowledgeRepository.Queryable()
  630. .Includes(x => x.SourceOrganize)
  631. .Includes(x => x.KnowledgeTypes)
  632. .Includes(x => x.HotspotType)
  633. .FirstAsync(p => p.Id == Id, HttpContext.RequestAborted);
  634. if (knowledge is null)
  635. throw UserFriendlyException.SameMessage("知识查询失败!");
  636. //转化
  637. var knowledgeShowInfoDto = _mapper.Map<KnowledgeDto>(knowledge);
  638. if (knowledgeShowInfoDto != null && !string.IsNullOrEmpty(knowledgeShowInfoDto.Content))
  639. knowledgeShowInfoDto.Content = _bulletinApplication.GetSiteUrls(knowledgeShowInfoDto.Content);
  640. //var type = await _knowledgeTypeRepository.GetAsync(knowledge.KnowledgeTypeId, HttpContext.RequestAborted);
  641. //if (type != null)
  642. //{
  643. // knowledgeShowInfoDto.KnowledgeTypeName = type.SpliceName;
  644. // knowledgeShowInfoDto.KnowledgeType = _mapper.Map<KnowledgeTypeDto>(type);
  645. //}
  646. //var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
  647. //if (hot != null)
  648. // knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
  649. //收藏
  650. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
  651. if (collect != null)
  652. knowledgeShowInfoDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
  653. //关联知识
  654. 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();
  655. if (knowledges.Any())
  656. knowledgeShowInfoDto.KnowledgeDtos = _mapper.Map<List<KnowledgeDto>>(knowledges);
  657. //关键词
  658. var knowledgeWords = await _knowledgeWrodRepository.Queryable().In(x => x.Id, knowledge.Keywords).ToListAsync();
  659. if (knowledgeWords.Any())
  660. knowledgeShowInfoDto.KeywordsDto = _mapper.Map<List<KnowledgeWordDto>>(knowledgeWords);
  661. if (knowledgeShowInfoDto.FileJson != null && knowledgeShowInfoDto.FileJson.Any())
  662. {
  663. var ids = knowledgeShowInfoDto.FileJson.Select(x => x.Id).ToList();
  664. knowledgeShowInfoDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
  665. }
  666. //var files = await _fileRepository.Queryable().Where(x => x.Key == knowledge.Id).ToListAsync();
  667. // if (files.Any()) knowledgeShowInfoDto.Files = _mapper.Map<List<FileDto>>(files);
  668. if (IsAddPv == true)
  669. _mediator.Publish(new GetKnowledgeInfoNotify(knowledge));
  670. return knowledgeShowInfoDto;
  671. }
  672. /// <summary>
  673. /// 知识详情--导出
  674. /// </summary>
  675. /// <param name="dto"></param>
  676. /// <returns></returns>
  677. [HttpPost("info/export")]
  678. public async Task<IActionResult> KnowledgeInfoExport([FromBody] KnowledgeInfoExportInDto dto)
  679. {
  680. if (dto.Ids.Length > 1)
  681. {
  682. var streams = await _knowApplication.KnowledgeInfoListExportAsync(dto, HttpContext.RequestAborted);
  683. byte[] fileBytes = _wordHelperService.ConvertZipStream(streams);
  684. var name = DateTime.Now.ToString("yyyyMMddHHmmss");
  685. return File(fileBytes, "application/octet-stream", $"{name}.zip");
  686. }
  687. var info = await _knowledgeRepository.GetAsync(dto.Ids[0]) ?? throw UserFriendlyException.SameMessage("知识不存在");
  688. return info.Content.HtmlToStream(dto.FileType).GetFileStreamResult(dto.FileType, info.Title, false);
  689. }
  690. /// <summary>
  691. /// 知识申请-关联知识-获取知识列表
  692. /// </summary>
  693. /// <returns></returns>
  694. [HttpGet("getknowledge")]
  695. public async Task<IReadOnlyList<KnowledgeCreateBMDataDto>> GetKnowledge()
  696. {
  697. var temp = await _knowledgeRepository
  698. .Queryable()
  699. .LeftJoin<SystemOrganize>((o, sys) => o.CreatorOrgId == sys.Id)
  700. //重新构建数据
  701. .Select((o, sys) => new
  702. {
  703. index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
  704. DepartmentId = sys.Id,
  705. Department = sys.Name,
  706. o.Id,
  707. o.Title,
  708. o.Status,
  709. o.Code,
  710. o.IsDeleted,
  711. o.ExpiredTime
  712. })
  713. //将结果合并成一个表
  714. .MergeTable()
  715. //取第一条数据
  716. .Where(x => x.IsDeleted == false)
  717. .Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
  718. .Where(d => d.index == 1 && d.Status == EKnowledgeStatus.OnShelf)
  719. .ToListAsync();
  720. //返回数据
  721. return _mapper.Map<IReadOnlyList<KnowledgeCreateBMDataDto>>(temp);
  722. }
  723. /// <summary>
  724. /// 我的草稿箱
  725. /// </summary>
  726. /// <param name="pagedDto"></param>
  727. /// <returns></returns>
  728. [HttpGet("mydraftslist")]
  729. public async Task<PagedDto<KnowledgeDataDto>> MyDraftsList([FromQuery] MyDraftsListPagedDto pagedDto)
  730. {
  731. var (total, items) = await _knowledgeRepository
  732. .Queryable()
  733. .Includes(it => it.User)
  734. .Where(p => p.CreatorId == _sessionContext.RequiredUserId && p.Status == EKnowledgeStatus.Drafts)
  735. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  736. .WhereIF(pagedDto.StartTime != null, d => d.CreationTime >= pagedDto.StartTime)
  737. .WhereIF(pagedDto.EndTime != null, d => d.CreationTime <= pagedDto.EndTime)
  738. .OrderByDescending(p => p.CreationTime)
  739. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  740. return new PagedDto<KnowledgeDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(items));
  741. }
  742. /// <summary>
  743. /// 知识库列表页面枚举值
  744. /// </summary>
  745. /// <returns></returns>
  746. [HttpGet("knowledge-status-data")]
  747. public Dictionary<string, dynamic> KnowledgeStatus()
  748. {
  749. var tabNames = new List<KeyValuePair<int, string>>
  750. {
  751. new KeyValuePair<int, string>(3, "已上架"),
  752. new KeyValuePair<int, string>(4, "已下架"),
  753. new KeyValuePair<int, string>(1, "审核中"),
  754. new KeyValuePair<int, string>(8, "草稿"),
  755. new KeyValuePair<int, string>(-1, "全部")
  756. };
  757. //var tabNames = EnumExts.GetDescriptions<EKnowledgeStatusRequest>();
  758. var tabNewDraftsNames = new List<KeyValuePair<int, string>>
  759. {
  760. new KeyValuePair<int, string>(-1, "全部"),
  761. new KeyValuePair<int, string>(0, "待提交"),
  762. new KeyValuePair<int, string>(5, "审核不通过"),
  763. };
  764. //var tabNewDraftsNames = EnumExts.GetDescriptions<EKnowledgeDraftTypeRequest>();
  765. var tabAuditingNames = new List<KeyValuePair<string, string>>
  766. {
  767. new KeyValuePair<string, string>("", "全部"),
  768. new KeyValuePair<string, string>("add", "新增审核"),
  769. new KeyValuePair<string, string>("update", "修改审核"),
  770. new KeyValuePair<string, string>("delete", "删除审核"),
  771. new KeyValuePair<string, string>("offshelf", "下架审核"),
  772. };
  773. //return _baseDataApplication
  774. // .FileType(EFileType.excel | EFileType.pdf)
  775. // .Build();
  776. var ignoreFileType = EFileType.excel | EFileType.pdf;
  777. var items = EnumExts.GetDescriptions<EFileType>();
  778. var filteredDictionary = items
  779. .Where(kvp => (ignoreFileType & (EFileType)kvp.Key) == 0)
  780. .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
  781. .ToList();
  782. return new Dictionary<string, dynamic>
  783. {
  784. { "fileType", filteredDictionary},
  785. { "tabNames", tabNames },
  786. { "tabNewDraftsNames", tabNewDraftsNames },
  787. { "tabAuditingNames", tabAuditingNames }
  788. };
  789. }
  790. /// <summary>
  791. /// 知识查询
  792. /// </summary>
  793. /// <param name="pagedDto"></param>
  794. /// <returns></returns>
  795. [HttpGet]
  796. public async Task<PagedDto<KnowledgeDataDto>> GetKnowList([FromQuery] KnowPagedListDto pagedDto)
  797. {
  798. return (await _knowApplication.GetKnowList(pagedDto, HttpContext.RequestAborted))
  799. .ToPaged();
  800. }
  801. /// <summary>
  802. /// 知识查询-导出
  803. /// </summary>
  804. /// <param name="dto"></param>
  805. /// <returns></returns>
  806. [HttpPost("export")]
  807. public async Task<IActionResult> GetKnowListExportAsync([FromBody] ExportExcelDto<KnowPagedListDto> dto)
  808. {
  809. var items = (await _knowApplication.GetKnowList(dto.QueryDto, HttpContext.RequestAborted)).Item2;
  810. return _exportApplication.GetExcelFile(dto, items, "知识明细导出");
  811. }
  812. /// <summary>
  813. /// 来电弹窗知识检索
  814. /// </summary>
  815. /// <param name="dto"></param>
  816. /// <returns></returns>
  817. [HttpPost("knowretrieval")]
  818. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrievalWindow([FromBody] KnowledgeRetrievalPagedListDto dto)
  819. {
  820. return (await _knowApplication.KnowRetrievalAsync(dto)).ToPaged();
  821. }
  822. /// <summary>
  823. /// 知识检索
  824. /// </summary>
  825. /// <param name="dto"></param>
  826. /// <returns></returns>
  827. [HttpGet("knowretrieval")]
  828. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowRetrieval([FromQuery] KnowledgeRetrievalPagedListDto dto)
  829. {
  830. return (await _knowApplication.KnowRetrievalAsync(dto)).ToPaged();
  831. }
  832. /// <summary>
  833. /// 知识检索页面基础数据
  834. /// </summary>
  835. /// <returns></returns>
  836. [HttpGet("knowretrieval/base_data")]
  837. public Dictionary<string, dynamic> GetKnowretrievalBaseData()
  838. {
  839. //return _baseDataApplication
  840. // .KnowledgeRetrievalType(new[] { 3, 4 })
  841. // .Build();
  842. var ignoreFileType = new[] { 3, 4 };
  843. return new Dictionary<string, dynamic>
  844. {
  845. { "knowledgeRetrievalType", EnumExts.GetDescriptions<EKnowledgeRetrievalType>().Where(m => !ignoreFileType.Contains(m.Key)).ToList() }
  846. };
  847. }
  848. /// <summary>
  849. /// 获取知识审批信息
  850. /// </summary>
  851. /// <param name="id"></param>
  852. /// <returns></returns>
  853. [HttpGet("audit_log")]
  854. public async Task<PagedDto<KnowledgeWorkFlowDto>> KnowRetrieval([FromQuery] AuditLogListPagedDto pagedDto)
  855. {
  856. var (total, temp) = await _knowledgeWorkFlowRepository
  857. .Queryable()
  858. .Includes(x => x.User)
  859. .Includes(x => x.SystemOrganize)
  860. .Includes(x => x.Workflow)
  861. .Where(x => x.KnowledgeId == pagedDto.id)
  862. .Where(x => x.IsDeleted == false)
  863. .OrderBy(x => x.CreationTime)
  864. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  865. return new PagedDto<KnowledgeWorkFlowDto>(total, _mapper.Map<IReadOnlyList<KnowledgeWorkFlowDto>>(temp));
  866. }
  867. /// <summary>
  868. /// 知识查重
  869. /// </summary>
  870. /// <param name="id"></param>
  871. /// <returns></returns>
  872. [HttpPost("finding_duplicate")]
  873. public async Task<bool> FindingDuplicate([FromBody] KnowledgeFindingDuplicateDto dto)
  874. {
  875. var any = await _knowledgeRepository.Queryable().Where(x => x.Status == EKnowledgeStatus.Auditing || x.Status >= EKnowledgeStatus.OnShelf)
  876. .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Equals(dto.Title))
  877. .WhereIF(!string.IsNullOrEmpty(dto.Summary), x => x.Summary.Equals(dto.Summary))
  878. .WhereIF(!string.IsNullOrEmpty(dto.Content), x => x.Content.Equals(dto.Content))
  879. .WhereIF(!string.IsNullOrEmpty(dto.Id), x => x.Id != dto.Id)
  880. .AnyAsync();
  881. return any;
  882. }
  883. /// <summary>
  884. /// 下载知识导入模板
  885. /// </summary>
  886. /// <returns></returns>
  887. [HttpGet("dl-template")]
  888. public object DownLoadKnowledgeTemplate()
  889. {
  890. return _exportApplication.ExportData(new List<KnowledgeImportTemplate>
  891. {
  892. new ()
  893. }, "知识模板.xlsx");
  894. }
  895. //[HttpPost("import-knowledge")]
  896. //public async Task<object> ImportKnowledge(IFormFile file)
  897. //{
  898. // using (var stream = new MemoryStream())
  899. // {
  900. // file.CopyTo(stream);
  901. // var list = MiniExcel.Query<KnowledgeImportTemplate>(stream).ToList();
  902. // int count = 0;
  903. // int errorCount = 0;
  904. // int addCount = 0;
  905. // int modifyCount = 0;
  906. // var allowSources = new Dictionary<string, string>
  907. // {
  908. // { "麻辣社区", "MLSQ" }, { "人民网", "RMW" }, { "省长信箱", "SZXX" }, { "问政四川", "WZSC" }
  909. // };
  910. // var errorMessage = new StringBuilder();
  911. // if (list == null || list.Count == 0)
  912. // {
  913. // return new { Count = count, ErrorCount = errorCount, AddCount = addCount, ModifyCount = modifyCount, ErrorMessage = "数据为空" };
  914. // }
  915. // count = list.Count;
  916. // var i = 0;
  917. // foreach (var item in list)
  918. // {
  919. // i++;
  920. // try
  921. // {
  922. // var validationResult = item.ValidateObject(false);
  923. // if (validationResult.NotNullOrEmpty())
  924. // {
  925. // errorMessage.Append($"第{i + 1}行: {validationResult}\r\n");
  926. // errorCount++;
  927. // continue;
  928. // }
  929. // var allowSource = allowSources.FirstOrDefault(m => m.Key == item.Source).Value;
  930. // if (allowSource.IsNullOrEmpty())
  931. // {
  932. // errorCount++;
  933. // continue;
  934. // }
  935. // var SourceCode = (ESource)Enum.Parse(typeof(ESource), allowSource);
  936. // var acceptType = _sysDicDataCacheManager.AcceptType
  937. // .FirstOrDefault(m => m.DicDataName == item.AcceptType);
  938. // if (acceptType == null)
  939. // {
  940. // errorMessage.Append($"第{i + 1}行: 不能通过受理类型 {item.AcceptType} 查询到对应的受理类型Code\r\n");
  941. // continue;
  942. // }
  943. // var order = await _orderRepository.GetAsync(x => x.ExternalId == item.ExternalId && x.Source == SourceCode,
  944. // HttpContext.RequestAborted) ?? new Orders.Order();
  945. // item.Source = SourceCode.ToString();
  946. // order = _mapper.Map(item, order);
  947. // order.AcceptTypeCode = acceptType.DicDataValue;
  948. // order.SourceChannel = SourceCode.GetDescription();
  949. // order.SourceChannelCode = ((int)SourceCode).ToString();
  950. // order.Status = EOrderStatus.Visited;
  951. // #region 处理数据开始
  952. // // order.Source = SourceCode; //来源
  953. // //处理热点
  954. // //处理一级热点
  955. // string hotspotId = "";
  956. // string hotspotName = "";
  957. // string hotspotFullName = "";
  958. // var hotspotOne = await _hotspotTypeRepository.Queryable()
  959. // .FirstAsync(x => x.HotSpotName == item.HotspotNameOne, HttpContext.RequestAborted);
  960. // if (hotspotOne != null)
  961. // {
  962. // hotspotId = hotspotOne.Id;
  963. // hotspotName = hotspotOne.HotSpotName;
  964. // hotspotFullName = hotspotOne.HotSpotFullName;
  965. // var hotspotTwo = await _hotspotTypeRepository.Queryable()
  966. // .FirstAsync(x => x.HotSpotName == item.HotspotNameTwo && x.ParentId == hotspotId, HttpContext.RequestAborted);
  967. // if (hotspotTwo != null)
  968. // {
  969. // hotspotId = hotspotTwo.Id;
  970. // hotspotName = hotspotTwo.HotSpotName;
  971. // hotspotFullName = hotspotTwo.HotSpotFullName;
  972. // var hotspotThree = await _hotspotTypeRepository.Queryable()
  973. // .FirstAsync(x => x.HotSpotName == item.HotspotNameThree && x.ParentId == hotspotId, HttpContext.RequestAborted);
  974. // if (hotspotThree != null)
  975. // {
  976. // hotspotId = hotspotThree.Id;
  977. // hotspotName = hotspotThree.HotSpotName;
  978. // hotspotFullName = hotspotThree.HotSpotFullName;
  979. // var hotspotFour = await _hotspotTypeRepository.Queryable()
  980. // .FirstAsync(x => x.HotSpotName == item.HotspotNameFour && x.ParentId == hotspotId,
  981. // HttpContext.RequestAborted);
  982. // if (hotspotFour != null)
  983. // {
  984. // hotspotId = hotspotFour.Id;
  985. // hotspotName = hotspotFour.HotSpotName;
  986. // hotspotFullName = hotspotFour.HotSpotFullName;
  987. // var hotspotFive = await _hotspotTypeRepository.Queryable()
  988. // .FirstAsync(x => x.HotSpotName == item.HotspotNameFive && x.ParentId == hotspotId,
  989. // HttpContext.RequestAborted);
  990. // if (hotspotFive != null)
  991. // {
  992. // hotspotId = hotspotFive.Id;
  993. // hotspotName = hotspotFive.HotSpotName;
  994. // hotspotFullName = hotspotFive.HotSpotFullName;
  995. // }
  996. // }
  997. // }
  998. // }
  999. // }
  1000. // order.HotspotId = hotspotId;
  1001. // order.HotspotName = hotspotName;
  1002. // order.HotspotSpliceName = hotspotFullName;
  1003. // //处理部门
  1004. // var orgOne = await _organizeRepository.Queryable()
  1005. // .FirstAsync(x => x.Name == item.OrgLevelOneName, HttpContext.RequestAborted);
  1006. // if (orgOne != null)
  1007. // {
  1008. // order.OrgLevelOneCode = orgOne.Id;
  1009. // order.OrgLevelOneName = orgOne.Name;
  1010. // var orgTwo = await _organizeRepository.Queryable()
  1011. // .FirstAsync(x => x.Name == item.OrgLevelTwoName && x.ParentId == order.OrgLevelOneCode, HttpContext.RequestAborted);
  1012. // if (orgTwo != null)
  1013. // {
  1014. // order.OrgLevelTwoCode = orgTwo.Id;
  1015. // order.OrgLevelTwoName = orgTwo.Name;
  1016. // }
  1017. // }
  1018. // //承办部门
  1019. // var ActualHandleOrg = await _organizeRepository.Queryable()
  1020. // .FirstAsync(x => x.Name == item.ActualHandleOrgName, HttpContext.RequestAborted);
  1021. // if (ActualHandleOrg != null)
  1022. // {
  1023. // order.ActualHandleOrgCode = ActualHandleOrg.Id;
  1024. // }
  1025. // //处理地址
  1026. // order.FullAddress = $"{order.Address}{order.Street}";
  1027. // order.FirstVisitResultCode = _sysDicDataCacheManager
  1028. // .GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction)
  1029. // .FirstOrDefault(m => m.DicDataName == item.VisitResult)?.DicDataValue
  1030. // ?? order.FirstVisitResultCode;
  1031. // #endregion
  1032. // if (order.Id.IsNullOrEmpty())
  1033. // {
  1034. // //order.Source = item;
  1035. // var id = await _orderDomainService.AddAsync(order, false, HttpContext.RequestAborted);
  1036. // if (!string.IsNullOrEmpty(id))
  1037. // {
  1038. // addCount++;
  1039. // }
  1040. // else
  1041. // {
  1042. // errorCount++;
  1043. // }
  1044. // }
  1045. // else
  1046. // {
  1047. // // _mapper.Map(item, order);
  1048. // await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
  1049. // modifyCount++;
  1050. // }
  1051. // }
  1052. // catch (Exception ex)
  1053. // {
  1054. // errorCount++;
  1055. // }
  1056. // }
  1057. // return new
  1058. // {
  1059. // Count = count,
  1060. // ErrorCount = errorCount,
  1061. // AddCount = addCount,
  1062. // ModifyCount = modifyCount,
  1063. // ErrorMessage = errorMessage.ToString()
  1064. // };
  1065. // }
  1066. //}
  1067. #endregion
  1068. #region 我的知识删除列表
  1069. /// <summary>
  1070. /// 我的知识删除列表页面枚举值
  1071. /// </summary>
  1072. /// <returns></returns>
  1073. [HttpGet("delete-status-data")]
  1074. public async Task<object> DeleteApplyStatus()
  1075. {
  1076. return EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>();
  1077. }
  1078. /// <summary>
  1079. /// 我的知识删除列表
  1080. /// </summary>
  1081. /// <param name="pagedDto"></param>
  1082. /// <returns></returns>
  1083. [HttpGet("deletelist")]
  1084. public async Task<PagedDto<KnowledgeDeleteApplyDataDto>> GetDeleteApplyList([FromQuery] KnowledgeDeletelPagedListDto pagedDto)
  1085. {
  1086. var (total, items) = await _knowledgeWorkFlowRepository
  1087. .Queryable(includeDeleted: true)
  1088. .Includes(it => it.Knowledge)
  1089. .Includes(it => it.User)
  1090. .Includes(it => it.SystemOrganize)
  1091. .Includes(it => it.Knowledge, it => it.KnowledgeType)
  1092. .Includes(it => it.Knowledge, it => it.HotspotType)
  1093. .Includes(it => it.Workflow)
  1094. .Where(d => d.CreatorId == _sessionContext.RequiredUserId && d.WorkflowModuleStatus == EKnowledgeApplyType.Delete && d.WorkflowId != null)
  1095. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  1096. .WhereIF(pagedDto.StartApplyTime.HasValue, d => d.CreationTime >= pagedDto.StartApplyTime)
  1097. .WhereIF(pagedDto.EndApplyTime.HasValue, d => d.CreationTime <= pagedDto.EndApplyTime)
  1098. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  1099. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  1100. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  1101. .OrderByDescending(p => p.CreationTime)
  1102. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  1103. return new PagedDto<KnowledgeDeleteApplyDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeDeleteApplyDataDto>>(items));
  1104. }
  1105. /// <summary>
  1106. /// 审核管理页面枚举值
  1107. /// </summary>
  1108. /// <returns></returns>
  1109. [HttpGet("approval-base-data")]
  1110. public async Task<object> ApprovalBaseData()
  1111. {
  1112. return new
  1113. {
  1114. EKnowledgeWorkFlowStatus = EnumExts.GetDescriptions<EKnowledgeWorkFlowStatus>(),
  1115. EKnowledgeApplyType = EnumExts.GetDescriptions<EKnowledgeApplyType>()
  1116. };
  1117. }
  1118. /// <summary>
  1119. /// 审核管理
  1120. /// </summary>
  1121. /// <param name="pagedDto"></param>
  1122. /// <returns></returns>
  1123. [HttpGet("approvedlist")]
  1124. public async Task<PagedDto<KnowledgeApprovalDataDto>> ApprovedList([FromQuery] KnowledgeApprovalPagedListDto pagedDto)
  1125. {
  1126. var (total, items) = await _knowledgeWorkFlowRepository
  1127. .Queryable(includeDeleted: true)
  1128. .Includes(it => it.Knowledge)
  1129. .Includes(it => it.User)
  1130. .Includes(it => it.SystemOrganize)
  1131. .Includes(it => it.Workflow, d => d.Steps)
  1132. .Where(it => it.WorkflowId != null)
  1133. .WhereIF(pagedDto.EKnowledgeApplyType.HasValue, d => d.WorkflowModuleStatus == pagedDto.EKnowledgeApplyType)
  1134. .WhereIF(pagedDto.EKnowledgeWorkFlowStatus.HasValue, d => d.WorkFlowApplyStatus == pagedDto.EKnowledgeWorkFlowStatus)
  1135. .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Knowledge.User.Name.Contains(pagedDto.Keyword!)
  1136. || d.Knowledge.SystemOrganize.Name.Contains(pagedDto.Keyword!)
  1137. || d.Knowledge.Title.Contains(pagedDto.Keyword!))
  1138. .OrderByDescending(p => p.CreationTime)
  1139. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
  1140. foreach (var item in items)
  1141. {
  1142. if (item.Workflow != null)
  1143. //item.CanHandle = item.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
  1144. item.CanHandle = item.Workflow.IsCanHandle(
  1145. _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles);
  1146. }
  1147. //处理是否可以办理
  1148. //items.ForEach(d => d.CanHandle = d.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgCode));
  1149. return new PagedDto<KnowledgeApprovalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApprovalDataDto>>(items));
  1150. }
  1151. /// <summary>
  1152. /// 工单受理知识检索
  1153. /// </summary>
  1154. /// <param name="pagedDto"></param>
  1155. /// <returns></returns>
  1156. [HttpGet("knowpopscreen")]
  1157. public async Task<PagedDto<KnowledgeRetrievalDataDto>> KnowPopScreen([FromQuery] KnowledgePopScreenPagedListDto pagedDto)
  1158. {
  1159. var orgid = string.Empty;
  1160. if (pagedDto.RetrievalType == EKnowledgeRetrievalType.Org && !string.IsNullOrEmpty(pagedDto.Keyword))
  1161. {
  1162. var organize = await _systemOrganizeRepository.GetAsync(x => x.Name == pagedDto.Keyword);
  1163. orgid = organize?.Id;
  1164. }
  1165. var (total, temp) = await _knowledgeRepository.Queryable()
  1166. .Includes(x => x.SourceOrganize)
  1167. .Where(d => d.Status == EKnowledgeStatus.OnShelf)
  1168. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Title && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Title.Contains(pagedDto.Keyword!))
  1169. .WhereIF(pagedDto.RetrievalType == EKnowledgeRetrievalType.Content && !string.IsNullOrEmpty(pagedDto.Keyword), d => d.Content.Contains(pagedDto.Keyword!))
  1170. .WhereIF(!string.IsNullOrEmpty(orgid) && pagedDto.RetrievalType == EKnowledgeRetrievalType.Org, x => x.CreatorOrgId.EndsWith(orgid!))
  1171. .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotId), p => p.HotspotId == pagedDto.HotspotId)
  1172. .OrderByDescending(p => p.CreationTime)
  1173. .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize);
  1174. return new PagedDto<KnowledgeRetrievalDataDto>(total, _mapper.Map<IReadOnlyList<KnowledgeRetrievalDataDto>>(temp));
  1175. }
  1176. ///// <summary>
  1177. ///// 新增-开始流程
  1178. ///// </summary>
  1179. ///// <param name="id">知识id</param>
  1180. ///// <param name="dto">流程开启参数</param>
  1181. ///// <returns></returns>
  1182. //[HttpPost("{id}/add-startflow")]
  1183. //public async Task AddStartFlow(string id, [FromBody] StartWorkflowDto dto)
  1184. //{
  1185. // await StartFlow(id, WorkflowModuleConsts.AddKnowledgeAsync, EKnowledgeApplyType.Add, dto);
  1186. //}
  1187. ///// <summary>
  1188. ///// 删除-开始流程
  1189. ///// </summary>
  1190. ///// <param name="id">知识id</param>
  1191. ///// <param name="dto">流程开启参数</param>
  1192. ///// <returns></returns>
  1193. //[HttpPost("{id}/remove-startflow")]
  1194. //public async Task RemoveStartFlow(string id, [FromBody] StartWorkflowDto dto)
  1195. //{
  1196. // await StartFlow(id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, dto);
  1197. //}
  1198. /// <summary>
  1199. /// 查询知识库办理流程开启参数-新增
  1200. /// </summary>
  1201. /// <returns></returns>
  1202. [HttpGet("add-flow-start")]
  1203. public async Task<NextStepsDto> GetAddFlowStartOptionsAsync()
  1204. {
  1205. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeAdd,
  1206. HttpContext.RequestAborted);
  1207. }
  1208. /// <summary>
  1209. /// 查询知识库办理流程开启参数-新增
  1210. /// </summary>
  1211. /// <returns></returns>
  1212. [HttpGet("update-flow-start")]
  1213. public async Task<NextStepsDto> GetUpdateFlowStartOptionsAsync()
  1214. {
  1215. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeUpdate,
  1216. HttpContext.RequestAborted);
  1217. }
  1218. /// <summary>
  1219. /// 查询知识库办理流程开启参数-删除
  1220. /// </summary>
  1221. /// <returns></returns>
  1222. [HttpGet("remove-flow-start")]
  1223. public async Task<NextStepsDto> GetRemoveFlowStartOptionsAsync()
  1224. {
  1225. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeDelete,
  1226. HttpContext.RequestAborted);
  1227. }
  1228. /// <summary>
  1229. /// 查询知识库办理流程开启参数-下架
  1230. /// </summary>
  1231. /// <returns></returns>
  1232. [HttpGet("offshelf-flow-start")]
  1233. public async Task<NextStepsDto> GetOffshelfFlowStartOptionsAsync()
  1234. {
  1235. return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeOffshelf,
  1236. HttpContext.RequestAborted);
  1237. }
  1238. /// <summary>
  1239. /// 开始流程
  1240. /// </summary>
  1241. /// <param name="id">知识ID</param>
  1242. /// <param name="moduleCode">知识模板编号</param>
  1243. /// <param name="eKnowledgeApplyType">申请类型</param>
  1244. /// <param name="dto">流程开启参数</param>
  1245. /// <returns></returns>
  1246. private async Task<string> StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
  1247. {
  1248. var knowledge = await _knowledgeRepository.GetAsync(id, HttpContext.RequestAborted);
  1249. if (knowledge == null)
  1250. throw UserFriendlyException.SameMessage("无效知识编号");
  1251. if (eKnowledgeApplyType == EKnowledgeApplyType.Delete)
  1252. {
  1253. if (knowledge.IsDeleted == true)
  1254. throw UserFriendlyException.SameMessage("知识删除失败");
  1255. }
  1256. //知识审批主表
  1257. await _knowledgeDomainService.AddWorkFlowAsync(id, eKnowledgeApplyType, HttpContext.RequestAborted);
  1258. dto.DefinitionModuleCode = moduleCode;
  1259. //dto.Title = knowledge.Title;
  1260. return await _workflowApplication.StartWorkflowAsync(dto, id, cancellationToken: HttpContext.RequestAborted);
  1261. }
  1262. #endregion
  1263. #region 知识库词库
  1264. /// <summary>
  1265. /// 新增知识库词库
  1266. /// </summary>
  1267. /// <param name="dtos"></param>
  1268. /// <returns></returns>
  1269. [HttpPost("knowledge_word")]
  1270. [LogFilter("新增知识库词库")]
  1271. public async Task Add([FromBody] KnowledgeWordAddDto dto)
  1272. {
  1273. var word = _mapper.Map<KnowledgeWord>(dto);
  1274. await _knowledgeWrodRepository.AddAsync(word, HttpContext.RequestAborted);
  1275. }
  1276. /// <summary>
  1277. /// 删除知识库词库
  1278. /// </summary>
  1279. /// <param name="dto"></param>
  1280. /// <returns></returns>
  1281. [HttpDelete("knowledge_word")]
  1282. [LogFilter("删除知识库词库")]
  1283. public async Task Delete([FromBody] KnowledgeWordDeleteDto dto)
  1284. {
  1285. await _knowledgeRepository.RemoveKnowledgeWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
  1286. }
  1287. /// <summary>
  1288. /// 更新知识库词库
  1289. /// </summary>
  1290. /// <param name="dto"></param>
  1291. /// <returns></returns>
  1292. [HttpPut("knowledge_word")]
  1293. [LogFilter("更新知识库词库")]
  1294. public async Task Update([FromBody] KnowledgeWordUpdateDto dto)
  1295. {
  1296. var word = await _knowledgeWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1297. if (word is null)
  1298. throw UserFriendlyException.SameMessage("无效知识库词库");
  1299. _mapper.Map(dto, word);
  1300. word.LastModificationName = _sessionContext.UserName;
  1301. await _knowledgeWrodRepository.UpdateAsync(word, HttpContext.RequestAborted);
  1302. }
  1303. /// <summary>
  1304. /// 获取知识库词库列表
  1305. /// </summary>
  1306. /// <param name="dto"></param>
  1307. /// <returns></returns>
  1308. [HttpGet("knowledge_word/list")]
  1309. public async Task<PagedDto<KnowledgeWordDto>> List([FromQuery] KnowledgeWordListDto dto)
  1310. {
  1311. var (total, items) = await _knowledgeWrodRepository.Queryable()
  1312. .WhereIF(!string.IsNullOrEmpty(dto.Tag), x => x.Tag == dto.Tag!)
  1313. .WhereIF(!string.IsNullOrEmpty(dto.Classify), x => x.Classify == dto.Classify!)
  1314. .WhereIF(dto.IsEnable.HasValue, x => x.IsEnable == dto.IsEnable)
  1315. .WhereIF(!string.IsNullOrEmpty(dto.Synonym), x => x.Synonym != null && x.Synonym.Contains(dto.Synonym!))
  1316. .OrderByDescending(x => x.CreationTime)
  1317. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1318. return new PagedDto<KnowledgeWordDto>(total, _mapper.Map<IReadOnlyList<KnowledgeWordDto>>(items));
  1319. }
  1320. /// <summary>
  1321. /// 获取知识库词库
  1322. /// </summary>
  1323. /// <param name="id"></param>
  1324. /// <returns></returns>
  1325. [HttpGet("knowledge_word/{id}")]
  1326. public async Task<KnowledgeWord> WordEntity(string id)
  1327. {
  1328. return await _knowledgeWrodRepository.Queryable()
  1329. .FirstAsync(x => x.Id == id);
  1330. }
  1331. /// <summary>
  1332. /// 获取知识库词库基本信息
  1333. /// </summary>
  1334. /// <returns></returns>
  1335. [HttpGet("knowledge_word/base")]
  1336. public async Task<object> Base()
  1337. {
  1338. var rsp = new
  1339. {
  1340. KnowledgeWordClassify = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.KnowledgeWordClassify),
  1341. };
  1342. return rsp;
  1343. }
  1344. #endregion
  1345. #region 知识纠错
  1346. /// <summary>
  1347. /// 新增知识纠错
  1348. /// </summary>
  1349. /// <param name="dtos"></param>
  1350. /// <returns></returns>
  1351. [HttpPost("knowledge_correction")]
  1352. [LogFilter("新增知识纠错")]
  1353. public async Task Add([FromBody] KnowledgeCorrectionAddDto dto)
  1354. {
  1355. var correction = _mapper.Map<KnowledgeCorrection>(dto);
  1356. await _knowledgeCorrectionRepository.AddAsync(correction, HttpContext.RequestAborted);
  1357. }
  1358. /// <summary>
  1359. /// 删除知识纠错
  1360. /// </summary>
  1361. /// <param name="dto"></param>
  1362. /// <returns></returns>
  1363. //[HttpDelete("knowledge_correction")]
  1364. //public async Task Delete([FromBody] KnowledgeCorrectionDeleteDto dto)
  1365. //{
  1366. // await _knowledgeCorrectionRepository.RemoveAsync(x => x.Id == dto.Id);
  1367. //}
  1368. /// <summary>
  1369. /// 更新知识纠错
  1370. /// </summary>
  1371. /// <param name="dto"></param>
  1372. /// <returns></returns>
  1373. //[HttpPut("knowledge_correction")]
  1374. //public async Task Update([FromBody] KnowledgeCorrectionUpdateDto dto)
  1375. //{
  1376. // var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1377. // if (correction is null)
  1378. // throw UserFriendlyException.SameMessage("无效知识纠错");
  1379. // _mapper.Map(dto, correction);
  1380. // await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  1381. //}
  1382. /// <summary>
  1383. /// 答复知识纠错
  1384. /// </summary>
  1385. /// <param name="dto"></param>
  1386. /// <returns></returns>
  1387. [HttpPut("knowledge_correction/Reply")]
  1388. [LogFilter("答复知识纠错")]
  1389. public async Task Reply([FromBody] KnowledgeCorrectionUpdateDto dto)
  1390. {
  1391. var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1392. if (correction is null)
  1393. throw UserFriendlyException.SameMessage("无效知识纠错");
  1394. _mapper.Map(dto, correction);
  1395. correction.ReplyTime = DateTime.Now;
  1396. correction.ReplyUserName = _sessionContext.UserName;
  1397. correction.State = ECorrectionState.AlreadyAnswered;
  1398. await _knowledgeCorrectionRepository.UpdateAsync(correction, HttpContext.RequestAborted);
  1399. }
  1400. /// <summary>
  1401. /// 获取知识纠错列表
  1402. /// </summary>
  1403. /// <param name="dto"></param>
  1404. /// <returns></returns>
  1405. [HttpGet("knowledge_correction/list")]
  1406. public async Task<PagedDto<KnowledgeCorrectionDto>> List([FromQuery] KnowledgeCorrectionListDto dto)
  1407. {
  1408. var typeSpliceName = string.Empty;
  1409. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  1410. {
  1411. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  1412. typeSpliceName = type?.SpliceName;
  1413. }
  1414. var (total, items) = await _knowledgeCorrectionRepository.Queryable(includeDeleted: true)
  1415. .Includes(x => x.Knowledge)
  1416. .Where(m => m.IsDeleted == false && m.Knowledge.IsDeleted == false)
  1417. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  1418. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  1419. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.Knowledge.KnowledgeType, typeSpliceName))
  1420. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.Knowledge.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
  1421. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1422. .OrderByDescending(x => x.CreationTime)
  1423. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1424. return new PagedDto<KnowledgeCorrectionDto>(total, _mapper.Map<IReadOnlyList<KnowledgeCorrectionDto>>(items));
  1425. }
  1426. /// <summary>
  1427. /// 获取知识库纠错
  1428. /// </summary>
  1429. /// <param name="id"></param>
  1430. /// <returns></returns>
  1431. [HttpGet("knowledge_correction/{id}")]
  1432. public async Task<KnowledgeCorrection> CorrectionEntity(string id)
  1433. {
  1434. return await _knowledgeCorrectionRepository.Queryable()
  1435. .Includes(x => x.Knowledge)
  1436. .FirstAsync(x => x.Id == id);
  1437. }
  1438. #endregion
  1439. #region 知识提问
  1440. /// <summary>
  1441. /// 新增知识提问
  1442. /// </summary>
  1443. /// <param name="dtos"></param>
  1444. /// <returns></returns>
  1445. [HttpPost("knowledge_questions")]
  1446. [LogFilter("新增知识提问")]
  1447. public async Task Add([FromBody] KnowledgeQuestionsAddDto dto)
  1448. {
  1449. var questions = _mapper.Map<KnowledgeQuestions>(dto);
  1450. await _knowledgeQuestionsRepository.AddAsync(questions, HttpContext.RequestAborted);
  1451. }
  1452. /// <summary>
  1453. /// 删除知识提问
  1454. /// </summary>
  1455. /// <param name="dto"></param>
  1456. /// <returns></returns>
  1457. //[HttpDelete("knowledge_questions")]
  1458. //public async Task Delete([FromBody] KnowledgeQuestionsDeleteDto dto)
  1459. //{
  1460. // await _knowledgeQuestionsRepository.RemoveAsync(x => x.Id == dto.Id);
  1461. //}
  1462. /// <summary>
  1463. /// 更新知识提问
  1464. /// </summary>
  1465. /// <param name="dto"></param>
  1466. /// <returns></returns>
  1467. //[HttpPut("knowledge_questions")]
  1468. //public async Task Update([FromBody] KnowledgeQuestionsUpdateDto dto)
  1469. //{
  1470. // var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1471. // if (questions is null)
  1472. // throw UserFriendlyException.SameMessage("无效知识提问");
  1473. // _mapper.Map(dto, questions);
  1474. // await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  1475. //}
  1476. /// <summary>
  1477. /// 答复知识提问
  1478. /// </summary>
  1479. /// <param name="dto"></param>
  1480. /// <returns></returns>
  1481. [HttpPut("knowledge_questions/Reply")]
  1482. [LogFilter("答复知识提问")]
  1483. public async Task Reply([FromBody] KnowledgeQuestionsUpdateDto dto)
  1484. {
  1485. var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1486. if (questions is null)
  1487. throw UserFriendlyException.SameMessage("无效知识提问");
  1488. _mapper.Map(dto, questions);
  1489. questions.ReplyTime = DateTime.Now;
  1490. questions.ReplyUserName = _sessionContext.UserName;
  1491. questions.State = ECorrectionState.AlreadyAnswered;
  1492. await _knowledgeQuestionsRepository.UpdateAsync(questions, HttpContext.RequestAborted);
  1493. }
  1494. /// <summary>
  1495. /// 获取知识提问列表
  1496. /// </summary>
  1497. /// <param name="dto"></param>
  1498. /// <returns></returns>
  1499. [HttpGet("knowledge_questions/list")]
  1500. public async Task<PagedDto<KnowledgeQuestionsDto>> List([FromQuery] KnowledgeQuestionsListDto dto)
  1501. {
  1502. var typeSpliceName = string.Empty;
  1503. if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
  1504. {
  1505. var type = await _knowledgeTypeRepository.GetAsync(x => x.Id == dto.KnowledgeTypeId);
  1506. typeSpliceName = type?.SpliceName;
  1507. }
  1508. var (total, items) = await _knowledgeQuestionsRepository.Queryable()
  1509. .Includes(x => x.Knowledge)
  1510. //.WhereIF(!string.IsNullOrEmpty(dto.KnowledgeTypeId), x => x.Knowledge.KnowledgeTypeId == dto.KnowledgeTypeId!)
  1511. //.WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => SqlFunc.JsonLike(x.Knowledge.KnowledgeType, typeSpliceName))
  1512. .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.Knowledge.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
  1513. .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName == dto.CreatorName!)
  1514. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1515. .OrderByDescending(x => x.CreationTime)
  1516. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1517. return new PagedDto<KnowledgeQuestionsDto>(total, _mapper.Map<IReadOnlyList<KnowledgeQuestionsDto>>(items));
  1518. }
  1519. /// <summary>
  1520. /// 获取知识提问
  1521. /// </summary>
  1522. /// <param name="id"></param>
  1523. /// <returns></returns>
  1524. [HttpGet("knowledge_questions/{id}")]
  1525. public async Task<KnowledgeQuestions> QuestionsEntity(string id)
  1526. {
  1527. return await _knowledgeQuestionsRepository.Queryable()
  1528. .Includes(x => x.Knowledge)
  1529. .FirstAsync(x => x.Id == id);
  1530. }
  1531. #endregion
  1532. #region 知识收藏
  1533. /// <summary>
  1534. /// 知识收藏列表
  1535. /// </summary>
  1536. /// <param name="dto"></param>
  1537. /// <returns></returns>
  1538. [HttpGet("knowledge_collect/list")]
  1539. public async Task<PagedDto<KnowledgeCollectDto>> List([FromQuery] KnowledgeCollectListDto dto)
  1540. {
  1541. var (total, items) = await _knowledgeCollectRepository.Queryable()
  1542. .Includes(x => x.Knowledge)
  1543. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Knowledge.Title.Contains(dto.Keyword!) || (x.Knowledge.Summary != null && x.Knowledge.Summary.Contains(dto.Keyword!)))
  1544. .WhereIF(dto.KnowledgeCollectGroupId.NotNullOrEmpty(), x => x.KnowledgeCollectGroupId == dto.KnowledgeCollectGroupId)
  1545. .Where(x => x.CreatorId == _sessionContext.UserId)
  1546. .Where(x => !string.IsNullOrEmpty(x.Knowledge.Id))
  1547. .Where(x => x.Collect!.Value)
  1548. .OrderByDescending(x => x.CreationTime)
  1549. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1550. return new PagedDto<KnowledgeCollectDto>(total, _mapper.Map<IReadOnlyList<KnowledgeCollectDto>>(items));
  1551. }
  1552. /// <summary>
  1553. /// 新增知识收藏
  1554. /// </summary>
  1555. /// <param name="dtos"></param>
  1556. /// <returns></returns>
  1557. [HttpPost("knowledge_collect")]
  1558. [LogFilter("知识收藏")]
  1559. public async Task Add([FromBody] KnowledgeCollectAddDto dto)
  1560. {
  1561. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1562. if (collect != null)
  1563. {
  1564. collect.Collect = dto.Collect;
  1565. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1566. }
  1567. else
  1568. {
  1569. var collectNew = _mapper.Map<KnowledgeCollect>(dto);
  1570. await _knowledgeCollectRepository.AddAsync(collectNew, HttpContext.RequestAborted);
  1571. }
  1572. var count = await _knowledgeCollectRepository.Queryable()
  1573. .Where(m => m.KnowledgeId == dto.KnowledgeId && m.Collect == true).CountAsync();
  1574. await _knowledgeRepository.Updateable()
  1575. .Where(m => m.Id == dto.KnowledgeId)
  1576. .SetColumns(m => m.CollectCount == count)
  1577. .ExecuteCommandAsync();
  1578. }
  1579. /// <summary>
  1580. /// 知识评分
  1581. /// </summary>
  1582. /// <param name="dto"></param>
  1583. /// <returns></returns>
  1584. [HttpDelete("knowledge_score")]
  1585. [LogFilter("知识评分")]
  1586. public async Task Delete([FromBody] KnowledgeCollectAddDto dto)
  1587. {
  1588. var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
  1589. if (collect != null)
  1590. {
  1591. if (collect.Score > 0)
  1592. throw UserFriendlyException.SameMessage("当前知识已经评分");
  1593. collect.Score = dto.Score;
  1594. await _knowledgeCollectRepository.UpdateAsync(collect, HttpContext.RequestAborted);
  1595. }
  1596. else
  1597. {
  1598. var questions = _mapper.Map<KnowledgeCollect>(dto);
  1599. await _knowledgeCollectRepository.AddAsync(questions, HttpContext.RequestAborted);
  1600. }
  1601. //计算总分
  1602. var sugar = _knowledgeCollectRepository.Queryable().Where(x => x.KnowledgeId == dto.KnowledgeId);
  1603. var count = await sugar.CountAsync();
  1604. var collects = await sugar.SumAsync(x => x.Score);
  1605. var score = collects / count;
  1606. var knowledge = await _knowledgeRepository.GetAsync(x => x.Id == dto.KnowledgeId);
  1607. if (knowledge != null)
  1608. {
  1609. knowledge.Score = decimal.Round(score.Value, 1);
  1610. await _knowledgeRepository.UpdateAsync(knowledge, HttpContext.RequestAborted);
  1611. }
  1612. }
  1613. #endregion
  1614. #region 知识评论
  1615. /// <summary>
  1616. /// 新增知识评论
  1617. /// </summary>
  1618. /// <param name="dto"></param>
  1619. /// <returns></returns>
  1620. [HttpPost("knowledge_comment")]
  1621. public async Task Add([FromBody] KnowledgeCommentAddDto dto)
  1622. {
  1623. var model = _mapper.Map<KnowledgeComment>(dto);
  1624. await _knowledgeCommentRepository.AddAsync(model, HttpContext.RequestAborted);
  1625. if (!string.IsNullOrEmpty(dto.ReplyId))
  1626. {
  1627. var comment = await _knowledgeCommentRepository.GetAsync(dto.ReplyId);
  1628. if (comment != null)
  1629. {
  1630. comment.ReplyNum++;
  1631. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1632. }
  1633. }
  1634. }
  1635. /// <summary>
  1636. /// 删除知识评论
  1637. /// </summary>
  1638. /// <param name="dto"></param>
  1639. /// <returns></returns>
  1640. [HttpDelete("knowledge_comment")]
  1641. public async Task Delete([FromBody] KnowledgeCommentDeleteDto dto)
  1642. {
  1643. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1644. if (comment is null)
  1645. throw UserFriendlyException.SameMessage("无效评论");
  1646. if (comment.CreatorId != _sessionContext.UserId)
  1647. throw UserFriendlyException.SameMessage("只有评论者可以删除当前评论");
  1648. await _knowledgeCommentRepository.RemoveAsync(x => x.Id == dto.Id);
  1649. }
  1650. /// <summary>
  1651. /// 修改知识评论
  1652. /// </summary>
  1653. /// <param name="dto"></param>
  1654. /// <returns></returns>
  1655. [HttpPut("knowledge_comment")]
  1656. public async Task Update([FromBody] KnowledgeCommentUpdateDto dto)
  1657. {
  1658. var comment = await _knowledgeCommentRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  1659. if (comment is null)
  1660. throw UserFriendlyException.SameMessage("无效评论");
  1661. _mapper.Map(dto, comment);
  1662. await _knowledgeCommentRepository.UpdateAsync(comment, HttpContext.RequestAborted);
  1663. }
  1664. /// <summary>
  1665. /// 知识评论列表
  1666. /// </summary>
  1667. /// <param name="dto"></param>
  1668. /// <returns></returns>
  1669. [HttpGet("knowledge_comment/list")]
  1670. public async Task<List<KnowledgeCommentDto>> List([FromQuery] KnowledgeCommentListDto dto)
  1671. {
  1672. var comments = await _knowledgeCommentRepository.Queryable()
  1673. .WhereIF(!string.IsNullOrEmpty(dto.KnowledgeId), x => x.KnowledgeId == dto.KnowledgeId)
  1674. .WhereIF(!string.IsNullOrEmpty(dto.ReplyId), x => x.ReplyId == dto.ReplyId)
  1675. .WhereIF(dto.All.HasValue && dto.All == false, x => x.CreatorId == _sessionContext.UserId)
  1676. .OrderByDescending(x => x.CreationTime)
  1677. .ToListAsync();
  1678. return new List<KnowledgeCommentDto>(_mapper.Map<IReadOnlyList<KnowledgeCommentDto>>(comments));
  1679. }
  1680. #endregion
  1681. #region 收藏分组
  1682. /// <summary>
  1683. /// 增加收藏分组
  1684. /// </summary>
  1685. [HttpPost("group")]
  1686. public async Task<KnowledgeCollectGroupOutDto> SaveKnowledgeCoolectGroupAsync([FromBody] KnowledgeCollectGroupInDto dto)
  1687. {
  1688. var entity = dto.Adapt<KnowledgeCollectGroup>();
  1689. if (await _knowledgeCollectGroupRepository
  1690. .Queryable()
  1691. .Where(m => m.Name == dto.Name && m.CreatorId == _sessionContext.UserId)
  1692. .AnyAsync() == true) throw UserFriendlyException.SameMessage("分组名重复, 请重新输入!");
  1693. var key = await _knowledgeCollectGroupRepository.AddAsync(entity);
  1694. if (key.IsNullOrEmpty()) throw UserFriendlyException.SameMessage("添加失败, 请重试");
  1695. var outDto = dto.Adapt<KnowledgeCollectGroupOutDto>();
  1696. outDto.Id = key;
  1697. return outDto;
  1698. }
  1699. /// <summary>
  1700. /// 删除收藏分组
  1701. /// </summary>
  1702. [HttpDelete("group")]
  1703. public async Task DeleteKnowledgeCoolectGroupAsync([FromQuery] string id)
  1704. {
  1705. var entity = await _knowledgeCollectGroupRepository.Queryable()
  1706. .Where(m => m.Id == id && m.CreatorId == _sessionContext.UserId)
  1707. .FirstAsync() ?? throw new UserFriendlyException("数据不存在");
  1708. entity.IsDeleted = true;
  1709. await _knowledgeCollectGroupRepository.UpdateAsync(entity);
  1710. await _knowledgeCollectRepository.Updateable()
  1711. .Where(m => m.KnowledgeCollectGroupId == id && m.CreatorId == _sessionContext.UserId)
  1712. .SetColumns(m => m.IsDeleted == true)
  1713. .ExecuteCommandAsync();
  1714. }
  1715. /// <summary>
  1716. /// 获取分组收藏列表
  1717. /// </summary>
  1718. /// <returns></returns>
  1719. [HttpGet("group")]
  1720. public async Task<PagedDto<KnowledgeCollectGroupOutDto>> GetKnowledgeCollectGroupListAsync([FromQuery] KnowledgeCollectGroupListInDto dto)
  1721. {
  1722. return (await _knowledgeCollectGroupRepository.Queryable()
  1723. .WhereIF(dto.Keyword.NotNullOrEmpty(), m => m.Name.Contains(dto.Keyword))
  1724. .Where(m => m.CreatorId == _sessionContext.UserId)
  1725. .Select<KnowledgeCollectGroupOutDto>()
  1726. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted)
  1727. ).ToPaged();
  1728. }
  1729. #endregion
  1730. #region PageView 浏览记录
  1731. /// <summary>
  1732. /// 浏览记录集合
  1733. /// </summary>
  1734. /// <param name="dto"></param>
  1735. /// <returns></returns>
  1736. [HttpGet("pageview")]
  1737. public async Task<PagedDto<PageViewOutDto>> GetPageViewListAsync([FromQuery] PageViewInDto dto)
  1738. {
  1739. return (await _knowApplication.GetPageViewListAsync(dto, HttpContext.RequestAborted))
  1740. .ToPaged();
  1741. }
  1742. /// <summary>
  1743. /// 浏览记录集合-导出
  1744. /// </summary>
  1745. /// <param name="dto"></param>
  1746. /// <returns></returns>
  1747. [HttpPost("pageview/export")]
  1748. public async Task<FileStreamResult> GetPageViewListAsync([FromBody] ExportExcelDto<PageViewInDto> dto)
  1749. {
  1750. var items = (await _knowApplication.GetPageViewListAsync(dto.QueryDto, HttpContext.RequestAborted))
  1751. .Item2;
  1752. return _exportApplication.GetExcelFile(dto, items, "浏览记录");
  1753. }
  1754. #endregion
  1755. #region 热词
  1756. /// <summary>
  1757. /// 新增热词
  1758. /// </summary>
  1759. /// <param name="dto"></param>
  1760. /// <returns></returns>
  1761. [HttpPost("hotword")]
  1762. public async Task AddKnowledgeHotWordAsync([FromBody] AddKnowledgeHotWordInDto dto)
  1763. {
  1764. await _knowApplication.AddKnowledgeHotWordAsync(dto, HttpContext.RequestAborted);
  1765. }
  1766. /// <summary>
  1767. /// 新增热词页面基础数据
  1768. /// </summary>
  1769. /// <param name="dto"></param>
  1770. /// <returns></returns>
  1771. [HttpGet("hotword/basedata")]
  1772. public Dictionary<string, dynamic> AddKnowledgeHotWordBaseDataAsync()
  1773. {
  1774. //return _baseDataApplication
  1775. // .KnowledgeHotWordType()
  1776. // .Build();
  1777. return new Dictionary<string, dynamic>
  1778. {
  1779. { "knowledgeHotWordType", EnumExts.GetDescriptions<EKnowledgeHotWordType>() }
  1780. };
  1781. }
  1782. /// <summary>
  1783. /// 热词集合
  1784. /// </summary>
  1785. /// <param name="dto"></param>
  1786. /// <returns></returns>
  1787. [HttpGet("hotword")]
  1788. public async Task<PagedDto<KnowledgeHotWordOutDto>> GetKnowledgeHotWordListAsync([FromQuery] KnowledgeHotWordInDto dto)
  1789. {
  1790. return (await _knowApplication.GetKnowledgeHotWordListAsync(dto, HttpContext.RequestAborted))
  1791. .ToPaged();
  1792. }
  1793. /// <summary>
  1794. /// 修改热词
  1795. /// </summary>
  1796. /// <param name="dto"></param>
  1797. /// <returns></returns>
  1798. [HttpPut("hotword")]
  1799. public async Task UpdateKnowledgeHotWordAsync([FromBody] UpdateKnowledgeHotWordInDto dto)
  1800. {
  1801. await _knowApplication.UpdateKnowledgeHotWordAsync(dto, HttpContext.RequestAborted);
  1802. }
  1803. /// <summary>
  1804. /// 删除热词
  1805. /// </summary>
  1806. /// <param name="id"></param>
  1807. /// <returns></returns>
  1808. [HttpDelete("hotword")]
  1809. public async Task DeleteKnowledgeHotWordAsync([FromQuery] string id)
  1810. {
  1811. await _knowledgeHotWordRepository
  1812. .RemoveAsync(id);
  1813. }
  1814. #endregion
  1815. #region 知识审批
  1816. /// <summary>
  1817. /// 查询待审批列表(new)
  1818. /// </summary>
  1819. [HttpGet("approve-paged")]
  1820. public async Task<PagedDto<KnowledgeApproveDto>> QueryKnowledgeApprovePaged([FromQuery] QueryKnowledgeApprovePagedRequest request)
  1821. {
  1822. var query = _knowledgeApproRepository.Queryable()
  1823. .Includes(d => d.Knowledge)
  1824. .WhereIF(request.KnowledgeApproveType.HasValue, d => d.KnowledgeApproveType == request.KnowledgeApproveType)
  1825. .WhereIF(request.IsPublic.HasValue, d => d.Knowledge.IsPublic == request.IsPublic)
  1826. .WhereIF(!string.IsNullOrEmpty(request.Keyword), d => d.CreatorName == request.Keyword
  1827. || d.CreatorOrgName == request.Keyword
  1828. || d.Knowledge.Title == request.Keyword
  1829. || d.Knowledge.SourceOrganize.Name == request.Keyword)
  1830. ;
  1831. if (request.HasApproved)
  1832. {
  1833. //已审批
  1834. query//.Includes(d => d.Approver)
  1835. .Where(d =>
  1836. d.ApproverId == _sessionContext.RequiredUserId
  1837. && d.KnowledgeApproveStatus != EKnowledgeApproveStatus.Unhandle);
  1838. }
  1839. else
  1840. {
  1841. //待审批
  1842. query.Where(d => d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle);
  1843. }
  1844. var (total, items) = await query.ToPagedListAsync(request, HttpContext.RequestAborted);
  1845. return new PagedDto<KnowledgeApproveDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApproveDto>>(items));
  1846. }
  1847. /// <summary>
  1848. /// 查询审核历史(new)
  1849. /// </summary>
  1850. /// <returns></returns>
  1851. [HttpGet("approve-history/{knowledgeId}")]
  1852. public async Task<IReadOnlyList<KnowledgeApproveDto>> QueryKnowledgeApproveByKnId(string knowledgeId)
  1853. {
  1854. var approves = await _knowledgeApproRepository.Queryable()
  1855. .Includes(d => d.Approver)
  1856. .Where(d => d.KnowledgeId == knowledgeId)
  1857. .OrderBy(d => d.CreationTime)
  1858. .ToListAsync(HttpContext.RequestAborted);
  1859. return _mapper.Map<IReadOnlyList<KnowledgeApproveDto>>(approves);
  1860. }
  1861. /// <summary>
  1862. /// 批量审核(new)
  1863. /// </summary>
  1864. /// <param name="request"></param>
  1865. /// <returns></returns>
  1866. [HttpPost("approve-batch")]
  1867. public async Task ApproveBatch([FromBody] ApproveBatchRequest request)
  1868. {
  1869. #region approve
  1870. var approves = await _knowledgeApproRepository.Queryable()
  1871. .Includes(d => d.Knowledge, x => x.KnowledgeTypes)
  1872. .Where(d => request.ApproveIds.Contains(d.Id) && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle)
  1873. .ToListAsync(HttpContext.RequestAborted);
  1874. foreach (var approve in approves)
  1875. {
  1876. var kn = approve.Knowledge;
  1877. switch (approve.KnowledgeApproveType)
  1878. {
  1879. case EKnowledgeApproveType.Add:
  1880. case EKnowledgeApproveType.Update:
  1881. // t: 上架 f: 驳回
  1882. if (request.IsSuccess)
  1883. {
  1884. kn.OnShelf();
  1885. }
  1886. else
  1887. {
  1888. kn.Status = EKnowledgeStatus.Revert;
  1889. }
  1890. break;
  1891. case EKnowledgeApproveType.Delete:
  1892. // t: 先下架,再删除 f: 驳回
  1893. if (request.IsSuccess)
  1894. {
  1895. kn.OffShelf();
  1896. kn.SoftDelete();
  1897. }
  1898. else
  1899. {
  1900. kn.Status = EKnowledgeStatus.Revert;
  1901. }
  1902. break;
  1903. case EKnowledgeApproveType.OffShelf:
  1904. // t: 下架 f: 上架
  1905. if (request.IsSuccess)
  1906. {
  1907. kn.OffShelf();
  1908. }
  1909. else
  1910. {
  1911. kn.Status = EKnowledgeStatus.OnShelf;
  1912. }
  1913. break;
  1914. default:
  1915. throw new ArgumentOutOfRangeException();
  1916. }
  1917. approve.Approve(_sessionContext.RequiredUserId, request.Opinion,
  1918. request.IsSuccess
  1919. ? EKnowledgeApproveStatus.Successed
  1920. : EKnowledgeApproveStatus.Failed);
  1921. }
  1922. //var kns = approves.Select(d => d.Knowledge).ToList();
  1923. //await _knowledgeRepository.UpdateRangeAsync(kns, HttpContext.RequestAborted);
  1924. await _knowledgeApproRepository.UpdateNav(approves)
  1925. .Include(d => d.Knowledge)
  1926. .ExecuteCommandAsync();
  1927. #endregion
  1928. #region push to ds
  1929. var pushApproves = approves.Where(d => d.KnowledgeApproveType != EKnowledgeApproveType.OffShelf)
  1930. .ToList();
  1931. if (!pushApproves.Any()) return;
  1932. //高效办成一件事配置
  1933. var cancelPublishOrderEnabled = _systemSettingCacheManager.GetSetting(SettingConstants.EfficientlyAccomplish)?.SettingValue[0];
  1934. foreach (var pushApprove in pushApproves)
  1935. {
  1936. var pushKnowledge = _mapper.Map<KnowledgeSendDto>(pushApprove.Knowledge);
  1937. pushKnowledge.CategoryCode = "01";
  1938. pushKnowledge.CategoryName = "公共服务";
  1939. if (!string.IsNullOrEmpty(cancelPublishOrderEnabled))
  1940. {
  1941. var isEfficientlyAccomplish = pushApprove.Knowledge.KnowledgeTypes.Any(
  1942. d => d.SpliceName.StartsWith(cancelPublishOrderEnabled));
  1943. //是高效,处理默认值
  1944. if (isEfficientlyAccomplish)
  1945. {
  1946. pushKnowledge.CategoryCode = "25";
  1947. pushKnowledge.CategoryName = "高效办成一件事";
  1948. }
  1949. }
  1950. switch (pushApprove.KnowledgeApproveType)
  1951. {
  1952. case EKnowledgeApproveType.Add:
  1953. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeAdd, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
  1954. break;
  1955. case EKnowledgeApproveType.Update:
  1956. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeUpdate, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
  1957. break;
  1958. case EKnowledgeApproveType.Delete:
  1959. await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
  1960. break;
  1961. case EKnowledgeApproveType.OffShelf:
  1962. default:
  1963. throw new ArgumentOutOfRangeException();
  1964. }
  1965. }
  1966. #endregion
  1967. //todo return $"总共: {dto.KnowledgeIds.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
  1968. }
  1969. #endregion
  1970. }
  1971. }