using Hotline.Application.FlowEngine; using Hotline.Article; using Hotline.Caching.Interfaces; using Hotline.FlowEngine.WorkflowModules; using Hotline.Permissions; using Hotline.Repository.SqlSugar.Extensions; using Hotline.Settings; using Hotline.Share.Dtos; using Hotline.Share.Dtos.Article; using Hotline.Share.Dtos.FlowEngine; using Hotline.Share.Dtos.Order; using Hotline.Share.Dtos.Users; using Hotline.Share.Enums.Article; using Hotline.Share.Requests; using Hotline.Users; using MapsterMapper; using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Writers; using MongoDB.Driver.Linq; using SqlSugar; using XF.Domain.Authentications; using XF.Domain.Exceptions; using XF.Domain.Repository; using XF.Utility.EnumExtensions; namespace Hotline.Api.Controllers { public class ArticleController : BaseController { private readonly IRepository _bulletinRepository; private readonly IMapper _mapper; private readonly ISystemOrganizeRepository _organizeRepository; private readonly IWorkflowApplication _workflowApplication; private readonly IRepository _circularRepository; private readonly ISessionContext _sessionContext; private readonly IRepository _circularRecordRepository; private readonly IRepository _circularReadGroupRepository; private readonly IRepository _userRepository; private readonly ICircularRecordDomainService _circularRecordDomainService; private readonly ISystemDicDataCacheManager _systemDicDataCacheManager; public ArticleController(IRepository bulletinRepository, IMapper mapper, ISystemDomainService systemDomainService, ISystemOrganizeRepository organizeRepository, IWorkflowApplication workflowApplication, IRepository circularRepository, ISessionContext sessionContext, IRepository circularRecordRepository, IRepository circularReadGroupRepository, IRepository userRepository, ICircularRecordDomainService circularRecordDomainService, ISystemDicDataCacheManager systemDicDataCacheManager) { _bulletinRepository = bulletinRepository; _mapper = mapper; _organizeRepository = organizeRepository; _workflowApplication = workflowApplication; _circularRepository = circularRepository; _sessionContext = sessionContext; _circularRecordRepository = circularRecordRepository; _circularReadGroupRepository = circularReadGroupRepository; _userRepository = userRepository; _circularRecordDomainService = circularRecordDomainService; _systemDicDataCacheManager = systemDicDataCacheManager; } #region 通知 /// /// 获取所有用户不分页 /// /// [HttpGet("alluser")] public async Task> GetAllUser() { var list = await _userRepository.Queryable(includeDeleted: false) .Includes(d => d.Account) .Includes(d => d.Organization) .OrderByDescending(x => x.CreationTime) .ToListAsync(); return new List(_mapper.Map>(list)); } /// /// 我的通知列表 /// /// /// [HttpGet("circular/muquery")] public async Task> GetMyCircularList([FromQuery] QueryCircularListRequestDto dto) { var (total, items) = await _circularRepository.Queryable() .Includes(x => x.CircularReadGroups) .WhereIF(!string.IsNullOrEmpty(dto.CircularTypeId), d => d.CircularTypeId == dto.CircularTypeId) .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title)) .WhereIF(dto.CircularTimeStart.HasValue, d => d.CircularTime >= dto.CircularTimeStart) .WhereIF(dto.CircularTimeEnd.HasValue, d => d.CircularTime <= dto.CircularTimeEnd) .WhereIF(dto.CircularState != null, d => d.CircularState == dto.CircularState) //.WhereIF(dto.IsRead!=null,d=>d.CircularReadGroups.Any(x=>x.IsRead == dto.IsRead) && (d.CircularReadGroups.Any(x => x.UserId == _sessionContext.RequiredUserId) || d.CircularReadGroups.Any(x => x.OrgId == _sessionContext.RequiredOrgId))) .WhereIF(dto.IsRead != null, d => (d.CircularReadGroups.Any(x => x.IsRead == dto.IsRead && x.UserId == _sessionContext.UserId)) || (d.CircularReadGroups.Any(x => x.IsRead == dto.IsRead && x.OrgId == _sessionContext.OrgId))) //.Where(d=>d.CircularReadGroups.Any(x=> x.UserId == _sessionContext.RequiredUserId) || d.CircularReadGroups.Any(x=>x.OrgId == _sessionContext.RequiredOrgId)) .OrderByDescending(d => d.CreationTime) .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted); return new PagedDto(total, _mapper.Map>(items)); } /// /// 查询通知列表 /// /// /// [Permission(EPermission.QueryCircularList)] [HttpGet("circular/query")] public async Task> QueryCircularList([FromQuery] QueryCircularListRequestDto dto) { var (total, items) = await _circularRepository.Queryable() .Includes(x => x.CircularReadGroups) .WhereIF(!string.IsNullOrEmpty(dto.CircularTypeId), d => d.CircularTypeId == dto.CircularTypeId) .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title)) .WhereIF(dto.CircularTimeStart.HasValue, d => d.CircularTime >= dto.CircularTimeStart) .WhereIF(dto.CircularTimeEnd.HasValue, d => d.CircularTime <= dto.CircularTimeEnd) .WhereIF(dto.CircularState != null, d => d.CircularState == dto.CircularState) .OrderByDescending(d => d.CreationTime) .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted); return new PagedDto(total, _mapper.Map>(items)); } /// /// 通知详情(内部) /// /// /// [Permission(EPermission.CircularEntity)] [HttpGet("circular/entity/{id}")] public async Task CircularEntity(string id) { var model = await _circularRepository.Queryable() .Includes(x => x.CircularReadGroups) .FirstAsync(x => x.Id == id, HttpContext.RequestAborted); return _mapper.Map(model); } /// /// 新增通知 /// /// /// [Permission(EPermission.AddCircular)] [HttpPost("circular/add")] public async Task AddCircular([FromBody] CircularFlowDto dto) { var model = _mapper.Map(dto.Data); model.CircularState = ECircularState.InReview; model.ReadedNum = 0; model.NeedReadNum = model.CircularReadGroups.Count; var id = await _circularRepository.AddAsync(model, HttpContext.RequestAborted); //子表 var list = dto.Data.CircularReadGroups; var readGroupList = new List(); foreach (var item in list) { var readGroup = _mapper.Map(item); readGroup.CircularId = id; readGroup.IsRead = false; readGroupList.Add(readGroup); } await _circularReadGroupRepository.AddRangeAsync(readGroupList); try { var startDto = _mapper.Map(dto.Workflow); startDto.DefinitionModuleCode = WorkflowModuleConsts.CircularApply; startDto.Title = model.Title; var workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, id, cancellationToken: HttpContext.RequestAborted); model.WorkflowId = workFlowId; await _circularRepository.UpdateAsync(model, HttpContext.RequestAborted); } catch (Exception ex) { await _circularRepository.RemoveAsync(id, false, HttpContext.RequestAborted); throw new UserFriendlyException($"新增通知流程失败!,{ex.Message}", "新增通知流程失败"); } } /// /// 列表页面基础信息 /// /// [HttpGet("circular/listbasedata")] public async Task CircularBaseData() { var rsp = new { CircularType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CircularType) }; return rsp; } /// /// 新增页面基础数据 /// /// [HttpGet("circular/addbasedata")] public async Task CircularAddBaseData() { var rsp = new { CircularType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CircularType), OrgsOptions = await _organizeRepository.GetOrgJson(), CircularTypeEnum = EnumExts.GetDescriptions() }; return rsp; } /// /// 通知阅读(内部) /// /// /// [HttpGet("circular/read/{id}")] public async Task CircularRead(string id) { var model = await _circularRepository.Queryable() .Includes(x => x.CircularReadGroups) .FirstAsync(x => x.Id == id, HttpContext.RequestAborted); //更新阅读信息 if (model.CircularType == ECircularType.Person) { //个人阅读 var readGroup = model.CircularReadGroups.FirstOrDefault(x => x.UserId == _sessionContext.RequiredUserId && !x.IsRead); if (readGroup != null) { readGroup.IsRead = true; readGroup.ReadTime = DateTime.Now; if (DateTime.Now > model.LostEfficacyTime) readGroup.IsTimeOut = true; else readGroup.IsTimeOut = false; await _circularReadGroupRepository.UpdateAsync(readGroup, HttpContext.RequestAborted); model.ReadedNum++; await _circularRepository.UpdateAsync(model, HttpContext.RequestAborted); //处理计数 await _circularRecordDomainService.RecordUserHandle(new List { _sessionContext.RequiredUserId }, false, cancellationToken: HttpContext.RequestAborted); } } else { //部门阅读 var readGroup = model.CircularReadGroups.FirstOrDefault(x => x.OrgId == _sessionContext.RequiredOrgId && !x.IsRead); if (readGroup != null) { readGroup.IsRead = true; readGroup.ReadTime = DateTime.Now; if (DateTime.Now > model.LostEfficacyTime) readGroup.IsTimeOut = true; else readGroup.IsTimeOut = false; await _circularReadGroupRepository.UpdateAsync(readGroup, HttpContext.RequestAborted); model.ReadedNum++; await _circularRepository.UpdateAsync(model, HttpContext.RequestAborted); //处理部门计数 await _circularRecordDomainService.RecordOrgHandle(new List { _sessionContext.RequiredOrgId }, false, cancellationToken: HttpContext.RequestAborted); } } return _mapper.Map(model); } /// /// 获取小红点计数 /// /// [HttpGet("megcount")] public async Task QueryMegCount() { var list = await _circularRecordRepository.Queryable().Where(x => x.UserId == _sessionContext.UserId || x.OrgId == _sessionContext.OrgId).ToListAsync(); if (list != null && list.Count > 0) { var rsp = new CircularRecordDto(); rsp.OrgCount = list.FirstOrDefault(x => x.CircularType == ECircularType.Org)?.RecordCount ?? 0; rsp.PersonCount = list.FirstOrDefault(x => x.CircularType == ECircularType.Person)?.RecordCount ?? 0; return rsp; } return new CircularRecordDto() { OrgCount = 0, PersonCount = 0 }; } /// /// 查询通知流程开启参数 /// /// [HttpGet("circular/startflow")] public async Task GetCircularFlowStartOptions() { return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.CircularApply, HttpContext.RequestAborted); } #endregion #region 公告 /// /// 查询公告列表 /// /// /// [Permission(EPermission.QueryBulletinList)] [HttpGet("bulletin/query")] public async Task> QueryBulletinList([FromQuery] QueryBulletinListRequestDto dto) { var (total, items) = await _bulletinRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(dto.BulletinTypeId), d => d.BulletinTypeId == dto.BulletinTypeId) .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title)) .WhereIF(dto.BulletinTimeStart.HasValue, d => d.BulletinTime >= dto.BulletinTimeStart) .WhereIF(dto.BulletinTimeEnd.HasValue, d => d.BulletinTime <= dto.BulletinTimeEnd) .WhereIF(dto.BulletinState != null, d => d.BulletinState == dto.BulletinState) .OrderByDescending(d => d.CreationTime) .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted); return new PagedDto(total, _mapper.Map>(items)); } /// /// 公告详情(内部) /// /// /// [Permission(EPermission.BulletinEntity)] [HttpGet("bulletin/entity/{id}")] public async Task BulletinEntity(string id) { var model = await _bulletinRepository.Queryable() .FirstAsync(x => x.Id == id, HttpContext.RequestAborted); return _mapper.Map(model); } /// /// 新增公告 /// /// /// [Permission(EPermission.AddBulletin)] [HttpPost("bulletin/add")] public async Task AddBulletin([FromBody] BulletinFlowDto dto) { var model = _mapper.Map(dto.Data); model.BulletinState = Share.Enums.Article.EBulletinState.InReview; model.ReadedNum = 0; var id = await _bulletinRepository.AddAsync(model, HttpContext.RequestAborted); try { var startDto = _mapper.Map(dto.Workflow); startDto.DefinitionModuleCode = WorkflowModuleConsts.BulletinApply; startDto.Title = model.Title; string workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, id, cancellationToken: HttpContext.RequestAborted); model.WorkflowId = workFlowId; await _bulletinRepository.UpdateAsync(model, HttpContext.RequestAborted); } catch (Exception ex) { await _bulletinRepository.RemoveAsync(id, false, HttpContext.RequestAborted); throw new UserFriendlyException($"新增公告流程失败!,{ex.Message}", "新增公告流程失败"); } } /// /// 列表页面基础数据 /// /// [HttpGet("bulletin/listbasedata")] public async Task BulletinListBaseData() { var rsp = new { BulletinType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.BulletinType) }; return rsp; } /// /// 新增页面基础数据 /// /// [HttpGet("bulletin/addbasedata")] public async Task BulletinAddBaseData() { var rsp = new { BulletinType = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.BulletinType), PushRanges = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.BulletinPushRange), OrgsOptions = await _organizeRepository.GetOrgJson(), }; return rsp; } /// /// 查询公告流程开启参数 /// /// [HttpGet("bulletin/startflow")] public async Task GetBulletinFlowStartOptions() { return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.BulletinApply, HttpContext.RequestAborted); } #endregion } }