|
@@ -1,5 +1,4 @@
|
|
|
-using DocumentFormat.OpenXml.Wordprocessing;
|
|
|
-using DotNetCore.CAP;
|
|
|
+using DotNetCore.CAP;
|
|
|
using Hotline.Api.Filter;
|
|
|
using Hotline.Application.Bulletin;
|
|
|
using Hotline.Application.ExportExcel;
|
|
@@ -13,14 +12,11 @@ using Hotline.FlowEngine.WorkflowModules;
|
|
|
using Hotline.FlowEngine.Workflows;
|
|
|
using Hotline.KnowledgeBase;
|
|
|
using Hotline.KnowledgeBase.Notifies;
|
|
|
-using Hotline.Permissions;
|
|
|
using Hotline.Repository.SqlSugar.Extensions;
|
|
|
-using Hotline.Repository.SqlSugar.Knowledge;
|
|
|
using Hotline.Repository.SqlSugar.Ts;
|
|
|
using Hotline.Settings;
|
|
|
using Hotline.Settings.Hotspots;
|
|
|
using Hotline.Share.Dtos;
|
|
|
-using Hotline.Share.Dtos.File;
|
|
|
using Hotline.Share.Dtos.FlowEngine;
|
|
|
using Hotline.Share.Dtos.Knowledge;
|
|
|
using Hotline.Share.Dtos.Order;
|
|
@@ -30,24 +26,28 @@ using Hotline.Share.Enums.KnowledgeBase;
|
|
|
using Hotline.Share.Mq;
|
|
|
using Hotline.Share.Tools;
|
|
|
using Hotline.Users;
|
|
|
-using J2N.Text;
|
|
|
using Mapster;
|
|
|
using MapsterMapper;
|
|
|
using MediatR;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
|
|
-using Org.BouncyCastle.Utilities.IO;
|
|
|
using SqlSugar;
|
|
|
using System.Text;
|
|
|
-using System.Threading;
|
|
|
using Hotline.Configurations;
|
|
|
+using Hotline.Share.Requests;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
using XF.Domain.Authentications;
|
|
|
using XF.Domain.Exceptions;
|
|
|
using XF.Domain.Repository;
|
|
|
using XF.Utility.EnumExtensions;
|
|
|
-using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
|
|
-using Hotline.Share.Dtos.Schedulings;
|
|
|
+using System.Threading;
|
|
|
+using Hotline.Caching.Interfaces;
|
|
|
+using Hotline.Import;
|
|
|
+using Hotline.Caching.Services;
|
|
|
+using Hotline.Share.Enums.Order;
|
|
|
+using MiniExcelLibs;
|
|
|
+using DocumentFormat.OpenXml.Wordprocessing;
|
|
|
+using Hotline.Pdf;
|
|
|
+using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
|
namespace Hotline.Api.Controllers
|
|
|
{
|
|
@@ -57,6 +57,9 @@ namespace Hotline.Api.Controllers
|
|
|
#region 注入
|
|
|
private readonly IExportApplication _exportApplication;
|
|
|
private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
|
|
|
+ private readonly IRepository<KnowledgeApprove> _knowledgeApproRepository;
|
|
|
+ private readonly ISystemSettingCacheManager _systemSettingCacheManager;
|
|
|
+ private readonly IPdfManager _pdfManager;
|
|
|
private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
|
|
|
private readonly IWordHelperService _wordHelperService;
|
|
|
private readonly BaseDataApplication _baseDataApplication;
|
|
@@ -82,7 +85,6 @@ namespace Hotline.Api.Controllers
|
|
|
private readonly ISystemOrganizeRepository _systemOrganizeRepository;
|
|
|
private readonly IFileRepository _fileRepository;
|
|
|
private readonly ICapPublisher _capPublisher;
|
|
|
- private readonly IRepository<KnowledgeRelationType> _knowledgeRelationTypeRepository;
|
|
|
private readonly IBulletinApplication _bulletinApplication;
|
|
|
private readonly IRepository<KnowledgeCollectGroup> _knowledgeCollectGroupRepository;
|
|
|
private readonly IRepository<KnowledgePv> _knowledgePvepository;
|
|
@@ -90,29 +92,28 @@ namespace Hotline.Api.Controllers
|
|
|
|
|
|
|
|
|
public KnowledgeController(
|
|
|
- IKnowledgeRepository knowledgeRepository,
|
|
|
- ISessionContext sessionContext,
|
|
|
- IKnowledgeDomainService knowledgeDomainService,
|
|
|
- IMapper mapper,
|
|
|
- IKnowApplication knowApplication,
|
|
|
- IMediator mediator,
|
|
|
- IWorkflowApplication workflowApplication,
|
|
|
- IWorkflowDomainService workflowDomainService,
|
|
|
- IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
|
|
|
- IRepository<User> userRepository,
|
|
|
- IRepository<KnowledgeType> knowledgeTypeRepository,
|
|
|
- IRepository<Hotspot> hotspotTypeRepository,
|
|
|
- IRepositoryTextSearch<KnowledgeTs> repositoryts,
|
|
|
- IRepository<KnowledgeWord> knowledgeWrodRepository,
|
|
|
- IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
|
|
|
- IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
|
|
|
- IRepository<KnowledgeCollect> knowledgeCollectRepository,
|
|
|
- ISystemDomainService systemDomainService,
|
|
|
- IRepository<KnowledgeComment> knowledgeCommentRepository,
|
|
|
- ISystemOrganizeRepository systemOrganizeRepository,
|
|
|
- IFileRepository fileRepository,
|
|
|
- ICapPublisher capPublisher,
|
|
|
- IRepository<KnowledgeRelationType> knowledgeRelationTypeRepository,
|
|
|
+ IKnowledgeRepository knowledgeRepository,
|
|
|
+ ISessionContext sessionContext,
|
|
|
+ IKnowledgeDomainService knowledgeDomainService,
|
|
|
+ IMapper mapper,
|
|
|
+ IKnowApplication knowApplication,
|
|
|
+ IMediator mediator,
|
|
|
+ IWorkflowApplication workflowApplication,
|
|
|
+ IWorkflowDomainService workflowDomainService,
|
|
|
+ IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
|
|
|
+ IRepository<User> userRepository,
|
|
|
+ IRepository<KnowledgeType> knowledgeTypeRepository,
|
|
|
+ IRepository<Hotspot> hotspotTypeRepository,
|
|
|
+ IRepositoryTextSearch<KnowledgeTs> repositoryts,
|
|
|
+ IRepository<KnowledgeWord> knowledgeWrodRepository,
|
|
|
+ IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
|
|
|
+ IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
|
|
|
+ IRepository<KnowledgeCollect> knowledgeCollectRepository,
|
|
|
+ ISystemDomainService systemDomainService,
|
|
|
+ IRepository<KnowledgeComment> knowledgeCommentRepository,
|
|
|
+ ISystemOrganizeRepository systemOrganizeRepository,
|
|
|
+ IFileRepository fileRepository,
|
|
|
+ ICapPublisher capPublisher,
|
|
|
IBulletinApplication bulletinApplication,
|
|
|
IRepository<KnowledgeCollectGroup> knowledgeCollectGroupRepository,
|
|
|
IExportApplication exportApplication,
|
|
@@ -121,8 +122,11 @@ namespace Hotline.Api.Controllers
|
|
|
IRepository<KnowledgePv> knowledgePvepository,
|
|
|
IRepository<KnowledgeWord> knowledgeWordRepository,
|
|
|
IRepository<KnowledgeHotWord> knowledgeWordHotRepository,
|
|
|
- IOptionsSnapshot<AppConfiguration> appOptions,
|
|
|
- IRepository<KnowledgeHotWord> knowledgeHotWordRepository)
|
|
|
+ IOptionsSnapshot<AppConfiguration> appOptions,
|
|
|
+ IRepository<KnowledgeHotWord> knowledgeHotWordRepository,
|
|
|
+ IRepository<KnowledgeApprove> knowledgeApproRepository,
|
|
|
+ ISystemSettingCacheManager _systemSettingCacheManager,
|
|
|
+ IPdfManager pdfManager)
|
|
|
{
|
|
|
_knowledgeRepository = knowledgeRepository;
|
|
|
_sessionContext = sessionContext;
|
|
@@ -146,7 +150,6 @@ namespace Hotline.Api.Controllers
|
|
|
_systemOrganizeRepository = systemOrganizeRepository;
|
|
|
_fileRepository = fileRepository;
|
|
|
_capPublisher = capPublisher;
|
|
|
- _knowledgeRelationTypeRepository = knowledgeRelationTypeRepository;
|
|
|
_bulletinApplication = bulletinApplication;
|
|
|
_knowledgeCollectGroupRepository = knowledgeCollectGroupRepository;
|
|
|
_exportApplication = exportApplication;
|
|
@@ -155,6 +158,9 @@ namespace Hotline.Api.Controllers
|
|
|
_knowledgePvepository = knowledgePvepository;
|
|
|
_knowledgeWordRepository = knowledgeWordRepository;
|
|
|
_knowledgeHotWordRepository = knowledgeHotWordRepository;
|
|
|
+ _knowledgeApproRepository = knowledgeApproRepository;
|
|
|
+ this._systemSettingCacheManager = _systemSettingCacheManager;
|
|
|
+ _pdfManager = pdfManager;
|
|
|
_appOptions = appOptions;
|
|
|
}
|
|
|
|
|
@@ -190,7 +196,7 @@ namespace Hotline.Api.Controllers
|
|
|
{
|
|
|
List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
|
|
|
types.ForEach(x => x.KnowledgeId = kn.Id);
|
|
|
- await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
|
|
|
+ //await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
|
|
|
}
|
|
|
if (dto.Workflow != null && !string.IsNullOrEmpty(kn.Id))
|
|
|
{
|
|
@@ -208,6 +214,30 @@ namespace Hotline.Api.Controllers
|
|
|
return kn.Id;
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-新增(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpPost]
|
|
|
+ public async Task<string> Add([FromBody] AddKnowledgeDto dto)
|
|
|
+ {
|
|
|
+ var kn = await _knowledgeDomainService.AddKnowledgeAsync(dto, HttpContext.RequestAborted);
|
|
|
+ return kn.Id;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-新增并发起审批(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpPost("add-and-approve")]
|
|
|
+ public async Task<string> AddAndApprove([FromBody] AddKnowledgeDto dto)
|
|
|
+ {
|
|
|
+ var kn = await _knowledgeDomainService.AddKnowledgeAsync(dto, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ var approve = await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Add, kn, null,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ return approve.Id;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 知识库-知识下架
|
|
|
/// </summary>
|
|
@@ -235,7 +265,7 @@ namespace Hotline.Api.Controllers
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- know.Status = EKnowledgeStatus.OffShelfAudit;
|
|
|
+ know.Status = EKnowledgeStatus.Auditing;
|
|
|
await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
|
|
|
|
|
|
var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
|
|
@@ -249,6 +279,27 @@ namespace Hotline.Api.Controllers
|
|
|
throw UserFriendlyException.SameMessage("知识下架失败");
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-知识下架(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpPost("offshelf")]
|
|
|
+ [LogFilter("知识下架")]
|
|
|
+ public Task OffShelf([FromBody] OffShelfKnowledgeDto dto) =>
|
|
|
+ _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-知识下架并发起审批(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpPost("offshelf-and-approve")]
|
|
|
+ [LogFilter("知识下架并发起审批")]
|
|
|
+ public async Task OffShelfAndApprove([FromBody] OffShelfKnowledgeDto dto)
|
|
|
+ {
|
|
|
+ var kn = await _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.OffShelf,
|
|
|
+ kn, dto.Opinion, HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 知识库-知识上架
|
|
|
/// </summary>
|
|
@@ -331,12 +382,12 @@ namespace Hotline.Api.Controllers
|
|
|
await _knowledgeRepository.UpdateNullAsync(knowledge, HttpContext.RequestAborted);
|
|
|
if (dto.Data.KnowledgeType.Any())
|
|
|
{
|
|
|
- var anyRelationTypes = await _knowledgeRelationTypeRepository.Queryable().Where(x => x.KnowledgeId == knowledge.Id).ToListAsync();
|
|
|
- if (anyRelationTypes.Any())
|
|
|
- await _knowledgeRelationTypeRepository.RemoveRangeAsync(anyRelationTypes);
|
|
|
- List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
|
|
|
- types.ForEach(x => x.KnowledgeId = dto.Data.Id);
|
|
|
- await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
|
|
|
+ //var anyRelationTypes = await _knowledgeRelationTypeRepository.Queryable().Where(x => x.KnowledgeId == knowledge.Id).ToListAsync();
|
|
|
+ //if (anyRelationTypes.Any())
|
|
|
+ // await _knowledgeRelationTypeRepository.RemoveRangeAsync(anyRelationTypes);
|
|
|
+ //List<KnowledgeRelationType> types = _mapper.Map<List<KnowledgeRelationType>>(dto.Data.KnowledgeType);
|
|
|
+ //types.ForEach(x => x.KnowledgeId = dto.Data.Id);
|
|
|
+ //await _knowledgeRelationTypeRepository.AddRangeAsync(types, HttpContext.RequestAborted);
|
|
|
}
|
|
|
if (dto.Workflow != null)
|
|
|
{
|
|
@@ -360,6 +411,62 @@ namespace Hotline.Api.Controllers
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-修改(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPut]
|
|
|
+ [LogFilter("知识修改")]
|
|
|
+ public Task Update([FromBody] UpdateKnowledgeDto dto) =>
|
|
|
+ _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 知识库-修改(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPut("update-and-approve")]
|
|
|
+ [LogFilter("知识修改")]
|
|
|
+ public async Task UpdateAndApprove([FromBody] UpdateKnowledgeAndApproveDto dto)
|
|
|
+ {
|
|
|
+ var kn = await _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ var exists = await _knowledgeApproRepository.Queryable()
|
|
|
+ .AnyAsync(d => d.KnowledgeId == dto.Id && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ if (exists)
|
|
|
+ throw new UserFriendlyException($"该知识存在待审批申请, knId: {dto.Id}", "该知识存在待审批申请, 请先审批");
|
|
|
+
|
|
|
+ if (kn.Status == EKnowledgeStatus.Drafts)
|
|
|
+ {
|
|
|
+ await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Add, kn, null,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Update, kn, dto.Opinion,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 批量更新公开状态(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("publish-batch")]
|
|
|
+ public async Task PublishBatch([FromBody] PublishBatchRequest request)
|
|
|
+ {
|
|
|
+ var kns = request.KnowledgeIds.Select(d => new Knowledge
|
|
|
+ {
|
|
|
+ Id = d,
|
|
|
+ IsPublic = request.IsPublic
|
|
|
+ }).ToList();
|
|
|
+ await _knowledgeRepository.Updateable(kns)
|
|
|
+ .UpdateColumns(d => d.IsPublic)
|
|
|
+ .ExecuteCommandAsync(HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 批量审核
|
|
|
/// </summary>
|
|
@@ -462,6 +569,36 @@ namespace Hotline.Api.Controllers
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 删除知识(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpDelete("remove")]
|
|
|
+ [LogFilter("删除知识")]
|
|
|
+ public async Task Remove([FromBody] DeleteKnowledgeDto dto)
|
|
|
+ {
|
|
|
+ var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
|
|
|
+ if (knowledge == null)
|
|
|
+ throw UserFriendlyException.SameMessage("无效知识库数据");
|
|
|
+ if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
|
|
|
+ throw UserFriendlyException.SameMessage("知识库数据不可删除");
|
|
|
+
|
|
|
+ if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
|
|
|
+ {
|
|
|
+ await _knowledgeRepository.RemoveAsync(knowledge, false, HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var exists = await _knowledgeApproRepository.Queryable()
|
|
|
+ .AnyAsync(d => d.KnowledgeId == dto.Id && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ if (exists)
|
|
|
+ throw new UserFriendlyException($"该知识存在待审批申请, knId: {dto.Id}", "该知识存在待审批申请, 请先审批");
|
|
|
+
|
|
|
+ await _knowledgeDomainService.AddKnowledgeApproveAsync(EKnowledgeApproveType.Delete, knowledge, dto.Opinion,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 增加搜索量
|
|
|
/// </summary>
|
|
@@ -487,17 +624,15 @@ namespace Hotline.Api.Controllers
|
|
|
[HttpGet("search_num/list")]
|
|
|
public async Task<PagedDto<KnowledgeDto>> SearchNumList([FromQuery] KnowledgeCollectListDto dto)
|
|
|
{
|
|
|
-
|
|
|
- var query = _knowledgeRepository.Queryable(false, true, false)
|
|
|
+ var query = _knowledgeRepository.Queryable()
|
|
|
.Where(x => x.Status == EKnowledgeStatus.OnShelf)
|
|
|
- .Where(m => m.IsDeleted == false)
|
|
|
.Where(x => (x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)
|
|
|
.OrderByDescending(x => x.SearchNum);
|
|
|
|
|
|
if (_sessionContext.OrgIsCenter == false)
|
|
|
{
|
|
|
- query = query.Where(m => m.KnowledgeType.Any(a => a.IsDeleted == false && a.KnowledgeType.KnowledgeTypeOrgs
|
|
|
- .Any(k => k.IsDeleted == false && k.OrgId.StartsWith(_sessionContext.OrgId))));
|
|
|
+ query = query.Where(m => m.KnowledgeTypes.Any(a => a.IsDeleted == false && a.Orgs
|
|
|
+ .Any(k => k.Id.StartsWith(_sessionContext.RequiredOrgId))));
|
|
|
query = query.Where(m => m.Attribution == "部门知识库");
|
|
|
}
|
|
|
var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
|
|
@@ -509,6 +644,7 @@ namespace Hotline.Api.Controllers
|
|
|
/// </summary>
|
|
|
/// <param name="Id"></param>
|
|
|
/// <returns></returns>
|
|
|
+ [Obsolete("请调用info/{Id}")]
|
|
|
[HttpGet("updateinfo/{Id}")]
|
|
|
public async Task<KnowledgeInfoDto> KnowledgeUpdateInfo(string Id)
|
|
|
{
|
|
@@ -544,15 +680,18 @@ namespace Hotline.Api.Controllers
|
|
|
/// <param name="IsAddPv">默认不增加,false不增加,true增加浏览量</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpGet("info/{Id}")]
|
|
|
- public async Task<KnowledgeInfoDto> KnowledgeInfo(string Id, bool? IsAddPv)
|
|
|
+ public async Task<KnowledgeDto> KnowledgeInfo(string Id, bool? IsAddPv)
|
|
|
{
|
|
|
- var knowledge = await _knowledgeDomainService.KnowledgeInfo(Id, HttpContext.RequestAborted);
|
|
|
+ var knowledge = await _knowledgeRepository.Queryable()
|
|
|
+ .Includes(x => x.SourceOrganize)
|
|
|
+ .Includes(x => x.KnowledgeTypes)
|
|
|
+ .Includes(x => x.HotspotType)
|
|
|
+ .FirstAsync(p => p.Id == Id, HttpContext.RequestAborted);
|
|
|
if (knowledge is null)
|
|
|
throw UserFriendlyException.SameMessage("知识查询失败!");
|
|
|
- if (knowledge.Workflow != null)
|
|
|
- knowledge.IsCanHandle = knowledge.Workflow.IsCanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles);
|
|
|
+
|
|
|
//转化
|
|
|
- var knowledgeShowInfoDto = _mapper.Map<KnowledgeInfoDto>(knowledge);
|
|
|
+ var knowledgeShowInfoDto = _mapper.Map<KnowledgeDto>(knowledge);
|
|
|
|
|
|
if (knowledgeShowInfoDto != null && !string.IsNullOrEmpty(knowledgeShowInfoDto.Content))
|
|
|
knowledgeShowInfoDto.Content = _bulletinApplication.GetSiteUrls(knowledgeShowInfoDto.Content);
|
|
@@ -563,9 +702,9 @@ namespace Hotline.Api.Controllers
|
|
|
// knowledgeShowInfoDto.KnowledgeTypeName = type.SpliceName;
|
|
|
// knowledgeShowInfoDto.KnowledgeType = _mapper.Map<KnowledgeTypeDto>(type);
|
|
|
//}
|
|
|
- var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
|
|
|
- if (hot != null)
|
|
|
- knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
|
|
|
+ //var hot = await _hotspotTypeRepository.GetAsync(knowledge.HotspotId, HttpContext.RequestAborted);
|
|
|
+ //if (hot != null)
|
|
|
+ // knowledgeShowInfoDto.HotspotName = hot.HotSpotFullName;
|
|
|
//收藏
|
|
|
var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
|
|
|
if (collect != null)
|
|
@@ -684,6 +823,7 @@ namespace Hotline.Api.Controllers
|
|
|
new KeyValuePair<int, string>(8, "草稿"),
|
|
|
new KeyValuePair<int, string>(-1, "全部")
|
|
|
};
|
|
|
+ //var tabNames = EnumExts.GetDescriptions<EKnowledgeStatusRequest>();
|
|
|
|
|
|
var tabNewDraftsNames = new List<KeyValuePair<int, string>>
|
|
|
{
|
|
@@ -691,14 +831,16 @@ namespace Hotline.Api.Controllers
|
|
|
new KeyValuePair<int, string>(0, "待提交"),
|
|
|
new KeyValuePair<int, string>(5, "审核不通过"),
|
|
|
};
|
|
|
+ //var tabNewDraftsNames = EnumExts.GetDescriptions<EKnowledgeDraftTypeRequest>();
|
|
|
+
|
|
|
|
|
|
var tabAuditingNames = new List<KeyValuePair<string, string>>
|
|
|
{
|
|
|
new KeyValuePair<string, string>("", "全部"),
|
|
|
- new KeyValuePair<string, string>("KnowledgeAdd", "新增审核"),
|
|
|
- new KeyValuePair<string, string>("KnowledgeUpdate", "修改审核"),
|
|
|
- new KeyValuePair<string, string>("KnowledgeDelete", "删除审核"),
|
|
|
- new KeyValuePair<string, string>("KnowledgeOffshelf", "下架审核"),
|
|
|
+ new KeyValuePair<string, string>("add", "新增审核"),
|
|
|
+ new KeyValuePair<string, string>("update", "修改审核"),
|
|
|
+ new KeyValuePair<string, string>("delete", "删除审核"),
|
|
|
+ new KeyValuePair<string, string>("offshelf", "下架审核"),
|
|
|
};
|
|
|
|
|
|
//return _baseDataApplication
|
|
@@ -821,6 +963,124 @@ namespace Hotline.Api.Controllers
|
|
|
return any;
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 下载知识导入模板(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("dl-template")]
|
|
|
+ public IActionResult DownLoadKnowledgeTemplate()
|
|
|
+ {
|
|
|
+ return _exportApplication.ExportData(new List<KnowledgeImportTemplate>
|
|
|
+ {
|
|
|
+ new ()
|
|
|
+ }, "知识模板.xlsx");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 导入知识(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="file"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("import-knowledge")]
|
|
|
+ public async Task<string> ImportKnowledge(IFormFile file)
|
|
|
+ {
|
|
|
+ using var stream = new MemoryStream();
|
|
|
+ await file.CopyToAsync(stream);
|
|
|
+ var items = stream.Query<KnowledgeImportTemplate>().ToList();
|
|
|
+ if (items == null || !items.Any()) throw new UserFriendlyException("未读取到数据");
|
|
|
+
|
|
|
+ if (items.Any(d => d.Attribution != "中心知识库" && d.Attribution != "部门知识库"))
|
|
|
+ throw UserFriendlyException.SameMessage("请正确输入知识归属");
|
|
|
+ if (items.Any(d => !string.IsNullOrEmpty(d.IsPublic) && d.IsPublic != "是" && d.IsPublic != "否"))
|
|
|
+ throw UserFriendlyException.SameMessage("请正确输入是否公开");
|
|
|
+ if (items.Any(d => string.IsNullOrEmpty(d.Title)))
|
|
|
+ throw UserFriendlyException.SameMessage("请输入标题");
|
|
|
+ if (items.Any(d => string.IsNullOrEmpty(d.Content)))
|
|
|
+ throw UserFriendlyException.SameMessage("请输入内容");
|
|
|
+
|
|
|
+ var titles = items.Select(d => d.Title).ToList();
|
|
|
+ var exists = await _knowledgeRepository.Queryable()
|
|
|
+ .Where(d => titles.Contains(d.Title))
|
|
|
+ .ToListAsync(HttpContext.RequestAborted);
|
|
|
+ if (exists.Any())
|
|
|
+ throw UserFriendlyException.SameMessage($"重复标题:{string.Join(',', exists.Select(d => d.Title))}");
|
|
|
+
|
|
|
+ var inputLevelOneTypes = items.Select(d => d.KnowledgeTypeLevelOne)
|
|
|
+ .Distinct().ToList();
|
|
|
+ var levelOneTypes = await _knowledgeTypeRepository.Queryable()
|
|
|
+ .Where(d => d.IsEnable && d.ParentId == null)
|
|
|
+ .ToListAsync(HttpContext.RequestAborted);
|
|
|
+ var existLevelOneNames = levelOneTypes.Select(d => d.Name);
|
|
|
+ var notExists = inputLevelOneTypes.Except(existLevelOneNames).ToList();
|
|
|
+ if (notExists.Any())
|
|
|
+ throw UserFriendlyException.SameMessage($"不存在的一级分类名称:{string.Join(',', notExists)}");
|
|
|
+
|
|
|
+ var sb = new StringBuilder();
|
|
|
+ var kns = new List<Knowledge>();
|
|
|
+ foreach (var item in items)
|
|
|
+ {
|
|
|
+ var kn = _mapper.Map<Knowledge>(item);
|
|
|
+ kn.SourceOrganizeId = _sessionContext.RequiredOrgId;
|
|
|
+ var knType = levelOneTypes.FirstOrDefault(d => d.Name == item.KnowledgeTypeLevelOne);
|
|
|
+ if (knType is null)
|
|
|
+ {
|
|
|
+ sb.Append($"错误一级分类:{item.KnowledgeTypeLevelOne}");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ kn.KnowledgeTypes = new List<KnowledgeType> { knType };
|
|
|
+ kn.IsPublic = item.IsPublic == "是";
|
|
|
+ kns.Add(kn);
|
|
|
+ }
|
|
|
+
|
|
|
+ await _knowledgeRepository.AddNav(kns)
|
|
|
+ .Include(d => d.KnowledgeTypes)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ var err = sb.ToString();
|
|
|
+ return string.IsNullOrEmpty(err)
|
|
|
+ ? $"导入{items.Count}条,成功{kns.Count}条"
|
|
|
+ : $"导入{items.Count}条,成功{kns.Count}条,{err}";
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 导出知识(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpGet("export-knowledge")]
|
|
|
+ public async Task<IActionResult> ExportKnowledge([FromQuery] ExportKnowledgeRequest request)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(request.Id))
|
|
|
+ throw new UserFriendlyException("无效知识编号");
|
|
|
+ var kn = await _knowledgeRepository.GetAsync(request.Id, HttpContext.RequestAborted);
|
|
|
+ if (kn is null)
|
|
|
+ throw new UserFriendlyException("无效知识编号");
|
|
|
+ var content = kn.Content
|
|
|
+ .Replace(" ", " ")
|
|
|
+ .Replace("&", "&")
|
|
|
+ .Replace(""", "\"")
|
|
|
+ .Replace(">", ">")
|
|
|
+ .Replace("<", "<")
|
|
|
+ ;
|
|
|
+
|
|
|
+
|
|
|
+ switch (request.ExportType)
|
|
|
+ {
|
|
|
+ case "pdf":
|
|
|
+ var fileName = $"{kn.Title}.pdf";
|
|
|
+ var stream = new MemoryStream();
|
|
|
+ _pdfManager.GeneratePdf(kn.Title, content, stream);
|
|
|
+ stream.Seek(0, SeekOrigin.Begin);
|
|
|
+ return new FileStreamResult(stream, "application/pdf")
|
|
|
+ {
|
|
|
+ FileDownloadName = fileName ?? DateTime.Now.ToString("yyyyMMddhhmmss") + ".pdf"
|
|
|
+ };
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
#endregion
|
|
|
|
|
|
#region 我的知识删除列表
|
|
@@ -951,7 +1211,7 @@ namespace Hotline.Api.Controllers
|
|
|
//[HttpPost("{id}/add-startflow")]
|
|
|
//public async Task AddStartFlow(string id, [FromBody] StartWorkflowDto dto)
|
|
|
//{
|
|
|
- // await StartFlow(id, WorkflowModuleConsts.KnowledgeAdd, EKnowledgeApplyType.Add, dto);
|
|
|
+ // await StartFlow(id, WorkflowModuleConsts.AddKnowledgeAsync, EKnowledgeApplyType.Add, dto);
|
|
|
//}
|
|
|
|
|
|
///// <summary>
|
|
@@ -1635,5 +1895,180 @@ namespace Hotline.Api.Controllers
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
+
|
|
|
+ #region 知识审批
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 查询待审批列表(new)
|
|
|
+ /// </summary>
|
|
|
+ [HttpGet("approve-paged")]
|
|
|
+ public async Task<PagedDto<KnowledgeApproveDto>> QueryKnowledgeApprovePaged([FromQuery] QueryKnowledgeApprovePagedRequest request)
|
|
|
+ {
|
|
|
+ var query = _knowledgeApproRepository.Queryable()
|
|
|
+ .Includes(d => d.Knowledge, s => s.KnowledgeTypes)
|
|
|
+ .WhereIF(request.KnowledgeApproveType.HasValue, d => d.KnowledgeApproveType == request.KnowledgeApproveType)
|
|
|
+ .WhereIF(request.IsPublic.HasValue, d => d.Knowledge.IsPublic == request.IsPublic)
|
|
|
+ .WhereIF(!string.IsNullOrEmpty(request.Keyword), d => d.CreatorName == request.Keyword
|
|
|
+ || d.CreatorOrgName == request.Keyword
|
|
|
+ || d.Knowledge.Title == request.Keyword
|
|
|
+ || d.Knowledge.SourceOrganize.Name == request.Keyword)
|
|
|
+ ;
|
|
|
+ if (request.HasApproved)
|
|
|
+ {
|
|
|
+ //已审批
|
|
|
+ query//.Includes(d => d.Approver)
|
|
|
+ .Where(d =>
|
|
|
+ d.ApproverId == _sessionContext.RequiredUserId
|
|
|
+ && d.KnowledgeApproveStatus != EKnowledgeApproveStatus.Unhandle);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //待审批
|
|
|
+ query.Where(d => d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle);
|
|
|
+ }
|
|
|
+
|
|
|
+ var (total, items) = await query.ToPagedListAsync(request, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ return new PagedDto<KnowledgeApproveDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApproveDto>>(items));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 查询审核历史(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("approve-history/{knowledgeId}")]
|
|
|
+ public async Task<IReadOnlyList<KnowledgeApproveDto>> QueryKnowledgeApproveByKnId(string knowledgeId)
|
|
|
+ {
|
|
|
+ var approves = await _knowledgeApproRepository.Queryable()
|
|
|
+ .Includes(d => d.Approver)
|
|
|
+ .Where(d => d.KnowledgeId == knowledgeId)
|
|
|
+ .OrderBy(d => d.CreationTime)
|
|
|
+ .ToListAsync(HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ return _mapper.Map<IReadOnlyList<KnowledgeApproveDto>>(approves);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 批量审核(new)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("approve-batch")]
|
|
|
+ public async Task ApproveBatch([FromBody] ApproveBatchRequest request)
|
|
|
+ {
|
|
|
+ #region approve
|
|
|
+
|
|
|
+ var approves = await _knowledgeApproRepository.Queryable()
|
|
|
+ .Includes(d => d.Knowledge, x => x.KnowledgeTypes)
|
|
|
+ .Where(d => request.ApproveIds.Contains(d.Id) && d.KnowledgeApproveStatus == EKnowledgeApproveStatus.Unhandle)
|
|
|
+ .ToListAsync(HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ foreach (var approve in approves)
|
|
|
+ {
|
|
|
+ var kn = approve.Knowledge;
|
|
|
+ switch (approve.KnowledgeApproveType)
|
|
|
+ {
|
|
|
+ case EKnowledgeApproveType.Add:
|
|
|
+ case EKnowledgeApproveType.Update:
|
|
|
+ // t: 上架 f: 驳回
|
|
|
+ if (request.IsSuccess)
|
|
|
+ {
|
|
|
+ kn.OnShelf();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ kn.Status = EKnowledgeStatus.Revert;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case EKnowledgeApproveType.Delete:
|
|
|
+ // t: 先下架,再删除 f: 驳回
|
|
|
+ if (request.IsSuccess)
|
|
|
+ {
|
|
|
+ kn.OffShelf();
|
|
|
+ kn.SoftDelete();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ kn.Status = EKnowledgeStatus.Revert;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case EKnowledgeApproveType.OffShelf:
|
|
|
+ // t: 下架 f: 上架
|
|
|
+ if (request.IsSuccess)
|
|
|
+ {
|
|
|
+ kn.OffShelf();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ kn.Status = EKnowledgeStatus.OnShelf;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new ArgumentOutOfRangeException();
|
|
|
+ }
|
|
|
+ approve.Approve(_sessionContext.RequiredUserId, request.Opinion,
|
|
|
+ request.IsSuccess
|
|
|
+ ? EKnowledgeApproveStatus.Successed
|
|
|
+ : EKnowledgeApproveStatus.Failed);
|
|
|
+ }
|
|
|
+
|
|
|
+ //var kns = approves.Select(d => d.Knowledge).ToList();
|
|
|
+ //await _knowledgeRepository.UpdateRangeAsync(kns, HttpContext.RequestAborted);
|
|
|
+
|
|
|
+ await _knowledgeApproRepository.UpdateNav(approves)
|
|
|
+ .Include(d => d.Knowledge)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region push to ds
|
|
|
+
|
|
|
+ var pushApproves = approves.Where(d => d.KnowledgeApproveType != EKnowledgeApproveType.OffShelf)
|
|
|
+ .ToList();
|
|
|
+ if (!pushApproves.Any()) return;
|
|
|
+
|
|
|
+ //高效办成一件事配置
|
|
|
+ var cancelPublishOrderEnabled = _systemSettingCacheManager.GetSetting(SettingConstants.EfficientlyAccomplish)?.SettingValue[0];
|
|
|
+ foreach (var pushApprove in pushApproves)
|
|
|
+ {
|
|
|
+ var pushKnowledge = _mapper.Map<KnowledgeSendDto>(pushApprove.Knowledge);
|
|
|
+ pushKnowledge.CategoryCode = "01";
|
|
|
+ pushKnowledge.CategoryName = "公共服务";
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(cancelPublishOrderEnabled))
|
|
|
+ {
|
|
|
+ var isEfficientlyAccomplish = pushApprove.Knowledge.KnowledgeTypes.Any(
|
|
|
+ d => d.SpliceName.StartsWith(cancelPublishOrderEnabled));
|
|
|
+ //是高效,处理默认值
|
|
|
+ if (isEfficientlyAccomplish)
|
|
|
+ {
|
|
|
+ pushKnowledge.CategoryCode = "25";
|
|
|
+ pushKnowledge.CategoryName = "高效办成一件事";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (pushApprove.KnowledgeApproveType)
|
|
|
+ {
|
|
|
+ case EKnowledgeApproveType.Add:
|
|
|
+ await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeAdd, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
|
|
|
+ break;
|
|
|
+ case EKnowledgeApproveType.Update:
|
|
|
+ await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeUpdate, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
|
|
|
+ break;
|
|
|
+ case EKnowledgeApproveType.Delete:
|
|
|
+ await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
|
|
|
+ break;
|
|
|
+ case EKnowledgeApproveType.OffShelf:
|
|
|
+ default:
|
|
|
+ throw new ArgumentOutOfRangeException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ //todo return $"总共: {dto.KnowledgeIds.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
}
|
|
|
}
|