using Hotline.Caching.Interfaces; using Hotline.FlowEngine; using Hotline.Repository.SqlSugar.Extensions; using Hotline.Settings; using Hotline.Settings.Hotspots; using Hotline.Settings.TimeLimits; using Hotline.Share.Dtos; using Hotline.Share.Dtos.Hotspots; using Hotline.Share.Dtos.Settings; using Hotline.Share.Enums.Order; using Hotline.Share.Enums.Settings; using MapsterMapper; using Microsoft.AspNetCore.Mvc; using SqlSugar; using StackExchange.Redis; using XF.Domain.Exceptions; using XF.Domain.Repository; using XF.Utility.EnumExtensions; namespace Hotline.Api.Controllers { /// /// 热点 /// public class HotspotController : BaseController { private readonly IRepository _hotspotTypeRepository; private readonly IMapper _mapper; private readonly ITimeLimitDomainService _timeLimitDomainService; private readonly ITimeLimitRepository _timeLimitRepository; private readonly ISystemDicDataCacheManager _sysDicDataCacheManager; private readonly IEventCategoryRepository _eventCategoryRepository; public HotspotController(IRepository hotspotTypeRepository, IMapper mapper, ITimeLimitDomainService timeLimitDomainService, ITimeLimitRepository timeLimitRepository, ISystemDicDataCacheManager sysDicDataCacheManager, IEventCategoryRepository eventCategoryRepository) { _hotspotTypeRepository = hotspotTypeRepository; _mapper = mapper; _timeLimitDomainService = timeLimitDomainService; _timeLimitRepository = timeLimitRepository; _sysDicDataCacheManager = sysDicDataCacheManager; _eventCategoryRepository = eventCategoryRepository; } #region 热点 /// /// 查询子项 /// [HttpGet("children")] public async Task> GetChildren([FromQuery] string? id) { var list = await _hotspotTypeRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(id), x => x.ParentId == id) .WhereIF(string.IsNullOrEmpty(id), x => x.ParentId == null || x.ParentId == "") .OrderBy(d => d.HotSpotName) .Select(x=> new Hotspot { Id = x.Id, HotSpotName = x.HotSpotName, ParentId = x.ParentId, HotSpotFullName = x.HotSpotFullName, ProvinceCode = x.ProvinceCode, HasChild = SqlFunc.Subqueryable().Where(d=>d.ParentId == x.Id).NotAny(), }).ToListAsync(); return list; } /// /// 名称检索热点树形 /// /// /// [HttpGet("children-hasname")] public async Task> GetChildrenHasName([FromQuery]string name) { var arr = _hotspotTypeRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(name), x => x.HotSpotName.Contains(name)).Select(x=>x.Id).ToList().Cast().ToArray(); //.ToTreeAsync(x => x.Children, it => it.ParentId, null); return await _hotspotTypeRepository.Queryable().Select(x => new Hotspot { Id = x.Id, HotSpotName = x.HotSpotName, ParentId = x.ParentId, HotSpotFullName = x.HotSpotFullName, ProvinceCode = x.ProvinceCode, HasChild = SqlFunc.Subqueryable().Where(d => d.ParentId == x.Id).NotAny(), }).ToTreeAsync(x => x.Children, it => it.ParentId,"", arr); } /// /// 查询热点数据(包含所有根目录及所查热点的所有上级对象) /// /// 编辑页面使用 /// /// /// /// [HttpGet("{id}/with-parents")] public async Task> GetWithParents(string id) { var targetList = await _hotspotTypeRepository.Queryable() .ToTreeAsync(d => d.Children, d => d.ParentId, null, new[] { id }); var topIds = targetList.Select(d => d.Id); var hotspots = await _hotspotTypeRepository.Queryable() .Where(d => string.IsNullOrEmpty(d.ParentId) && !topIds.Contains(d.Id)) .ToListAsync(); hotspots.AddRange(targetList); return hotspots.OrderBy(d => d.HotSpotName).ToList(); } #endregion #region 事件分类管理 /// /// 事件全部树形 /// /// [HttpGet("event/tree")] public async Task> GetEventAllTree() { return await _eventCategoryRepository.Queryable() .OrderBy(d => d.OrderBy) .ToTreeAsync(x => x.Children, it => it.ParentId,null); } /// /// 查询子项 /// /// /// [HttpGet("event/children")] public async Task> GetEventChildren([FromQuery]string? id) { var list = await _eventCategoryRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(id),x => x.ParentId == id) .WhereIF(string.IsNullOrEmpty(id),x=>x.ParentId == null || x.ParentId=="") .OrderBy(d => d.EventName) .Select(x => new EventCategory { Id = x.Id, EventName = x.EventName, ParentId = x.ParentId, EventFullName = x.EventFullName, HasChild = SqlFunc.Subqueryable().Where(d => d.ParentId == x.Id).NotAny() }).ToListAsync(); return list; } /// /// 名称检索事件树形 /// /// /// [HttpGet("event/children-hasname")] public async Task> GetEventChildrenHasName([FromQuery]string name) { var arr = _eventCategoryRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(name), x => x.EventName.Contains(name)).Select(x => x.Id).ToList().Cast().ToArray(); return await _eventCategoryRepository.Queryable().Select( x=> new EventCategory { Id = x.Id, EventName = x.EventName, ParentId = x.ParentId, EventFullName = x.EventFullName, HasChild = SqlFunc.Subqueryable().Where(d => d.ParentId == x.Id).NotAny() }).ToTreeAsync(x => x.Children, it => it.ParentId, "", arr); } #region 管理接口 /// /// 新增事件 /// /// /// [HttpPost("event/add-event")] public async Task AddEventCategory([FromBody]AddEventCategoryDto dto) { //验证重复 var ishas = await _eventCategoryRepository.AnyAsync(x => x.ParentId == dto.ParentId && x.EventName == dto.EventName); if (ishas) { throw UserFriendlyException.SameMessage("同级别下存在相同名字的事件,不能添加"); } var model = _mapper.Map(dto); (model.Id,model.EventFullName) = await _eventCategoryRepository.GetNewEventCodeAsync(dto.ParentId,model.EventName); await _eventCategoryRepository.AddAsync(model, HttpContext.RequestAborted); } /// /// 删除事件 /// /// /// [HttpDelete("event/del-event")] public async Task DelEventCategory(string[] id) { var list = await _eventCategoryRepository.Queryable().In(id).ToListAsync(HttpContext.RequestAborted); await _eventCategoryRepository.RemoveRangeAsync(list, HttpContext.RequestAborted); } #endregion #endregion #region 时限管理 /// /// 获取时限配置页面基础数据 /// /// [HttpGet("timelimit-basedata")] public async Task GetTimeLimitBaseData() { return new { //ModuleOptions = WorkflowModule.Modules.ToList(),//todo TimeType = EnumExts.GetDescriptions(), BaseData = TimeLimitBaseData.GetBaseData(), //AcceptType = EnumExts.GetDescriptions(), AcceptType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType), //PushType = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.PushType), SourceChannel = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel), IdentityType = EnumExts.GetDescriptions(), OrderType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.OrderType), CertType = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.LicenceType), EmergencyLevel = EnumExts.GetDescriptions() }; } /// /// 新增时限管理 /// /// /// 数据主键 [HttpPost("add-timelimit")] public async Task AddTimeLimit([FromBody] AddTimeLimitDto dto) { var model = _mapper.Map(dto); model.TimeLimitState = ETimeLimitState.Draft; return await _timeLimitDomainService.AddAsync(model, HttpContext.RequestAborted); } /// /// 修改时限管理 /// /// /// [HttpPost("update-timelimit")] public async Task UpdateTimeLimit([FromBody] UpdateTimeLimitDto dto) { var model = _mapper.Map(dto); await _timeLimitDomainService.UpdateAsync(model, HttpContext.RequestAborted); } /// /// 获取对象 /// /// /// [HttpGet("timelimit/{id}")] public async Task GetTimeLimit(string id) { return await _timeLimitRepository.GetAsync(id, HttpContext.RequestAborted); } /// /// 获取时限管理列表 /// /// /// [HttpGet("paged-timelimit")] public async Task> QueryPagedTimeLimit([FromQuery] QueryPagedTimeLimitPagedDto dto) { var (total, items) = await _timeLimitRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.TimeLimitName.Contains(dto.Keyword!)) .OrderByDescending(d => d.CreationTime) .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted); return new PagedDto(total, _mapper.Map>(items)); } /// /// 删除时限(草稿) /// /// /// [HttpDelete("deltimelimit")] public async Task DelTimeLimit(string id) { var model = await _timeLimitRepository.GetAsync(id, HttpContext.RequestAborted); if (model == null) { throw UserFriendlyException.SameMessage("无效数据"); } if (model.TimeLimitState != ETimeLimitState.Draft) { throw UserFriendlyException.SameMessage("无法删除,请刷新页面"); } await _timeLimitRepository.RemoveAsync(id, true, HttpContext.RequestAborted); } /// /// 启用时限 /// /// /// [HttpGet("enable-timelimit/{id}")] public async Task EnableTimeLimit(string id) { var model = await _timeLimitRepository.GetAsync(id, HttpContext.RequestAborted); if (model == null) { throw UserFriendlyException.SameMessage("无效数据"); } if (model.TimeLimitState == ETimeLimitState.Enable) { throw UserFriendlyException.SameMessage("该配置已生效"); } var list = await _timeLimitRepository.QueryAsync(x => x.WorkflowCode == model.WorkflowCode && x.TimeLimitState == ETimeLimitState.Enable); list.ForEach(x => x.TimeLimitState = ETimeLimitState.Disable); model.TimeLimitState = ETimeLimitState.Enable; list.Add(model); await _timeLimitRepository.UpdateRangeAsync(list, HttpContext.RequestAborted); } /// /// 禁用时限 /// /// /// [HttpGet("disable-timelimit/{id}")] public async Task DisableTimeLimit(string id) { var model = await _timeLimitRepository.GetAsync(id, HttpContext.RequestAborted); if (model == null) { throw UserFriendlyException.SameMessage("无效数据"); } if (model.TimeLimitState == ETimeLimitState.Draft) { throw UserFriendlyException.SameMessage("该配置未生效,无法禁用"); } if (model.TimeLimitState == ETimeLimitState.Disable) { throw UserFriendlyException.SameMessage("该配置已禁用"); } model.TimeLimitState = ETimeLimitState.Disable; await _timeLimitRepository.UpdateAsync(model, HttpContext.RequestAborted); } #endregion #region 工作日设定 #endregion } }