非羁押人员管理平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1134 lines
57 KiB

using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCommonFences;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCommonFences.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.IM.Notifies;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Input;
using ATS.NonCustodial.Application.Impl.Business.IM;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Business.EarlyWarning;
using ATS.NonCustodial.Domain.Entities.Business.IM;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using ATS.NonCustodial.Shared.Extensions;
using ATS.NonCustodial.Shared.Helpers;
using AutoMapper.QueryableExtensions;
using Castle.Components.DictionaryAdapter;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System.Net;
using System.Text;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Business
{
/// <summary>
/// 预警提醒管理(实时)
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-06-05 11:30 PM
/// <remarks>
/// 1、【脱离监管区域】被监管人触发电子围栏,会发送预警并记录违规。
/// 2、【同案人员地点靠近】被监管人靠近同案其他成员的距离小于案件接近等级,会发送预警并记录违规。
/// 3、【未打卡】被监管人未按照要求打卡,每次会触发一次违规。在被监管人在非休息时间内打卡时间间隔超过设置的间隔,则需要进行预警,提示XXX未打卡。
/// 4、【脱离监管区域、未打卡、未学习、同案人员地点靠近、失联】监管人在移动端手动给该监管人进行告警,记录一次违规。
/// 5、【设备拆除】手环中有一个数据为是否被拆除,如果为是的话,则会触发拆除的预警违规。
/// 总共的类型为:脱离监管区域、同案人员地点靠近、未打卡、未学习、设备拆除
/// </remarks>
[DynamicApi(Area = "admin")]
public class AppEarlyWarningService : AdminCommonService, IAppEarlyWarningService, IDynamicApi
{
#region Identity
private readonly IHubContext<NonCustodialHub> _hubContext;
private readonly IEfRepository<AppEarlyWarning, long> _appEarlyWarningRepository;
private readonly IEfRepository<AppEarlyWarningPushResult, long> _appEarlyWarningPushResultRepository;
private readonly IEfRepository<AppDeviceManagement, long> _appDeviceManagementRepository;
private readonly IEfRepository<AppEarlyWarningViewStatistics, long> _appEarlyWarningViewStatisticsRepository;
private readonly IAppCommonFenceService _appCommonFenceService;
private readonly IEfRepository<AppBusinessApplication, long> _appBusinessApplicationRepository;
private readonly IClientNotifyService _clientNotifyService;
private readonly IEfRepository<AppEarlyWarningRule, long> _appEarlyWarningRuleRepository;
private readonly IAppCaseManagementService _appCaseManagementService;
private readonly IUserService _userService;
/// <summary>
///
/// </summary>
/// <param name="appEarlyWarningRepository"></param>
/// <param name="hubContext"></param>
/// <param name="appCaseManagementRepository"></param>
/// <param name="appCaseSupervisorRepository"></param>
/// <param name="appSupervisedPersonRepository"></param>
/// <param name="userService"></param>
/// <param name="appDictionaryService"></param>
/// <param name="appDeviceManagementRepository"></param>
/// <param name="appSessionInformationRepository"></param>
/// <param name="appCommonFenceService"></param>
public AppEarlyWarningService(IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
IEfRepository<AppEarlyWarningPushResult, long> appEarlyWarningPushResultRepository,
IHubContext<NonCustodialHub> hubContext,
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository,
IEfRepository<AppCaseSupervisedPerson, long> appSupervisedPersonRepository,
IUserService userService,
IAppDictionaryService appDictionaryService,
IEfRepository<AppDeviceManagement, long> appDeviceManagementRepository,
IEfRepository<AppSessionInformation, long> appSessionInformationRepository,
IAppCommonFenceService appCommonFenceService,
IAppCaseManagementService appCaseManagementService,
IEfRepository<AppBusinessApplication, long> appBusinessApplicationRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> appSupervisedPersonRealTimeLocationRepository,
IClientNotifyService clientNotifyService,
IEfRepository<AppEarlyWarningViewStatistics, long> appEarlyWarningViewStatisticsRepository,
IEfRepository<AppEarlyWarningRule, long> appEarlyWarningRuleRepository)
: base(
appCaseManagementRepository,
appCaseSupervisorRepository,
appSupervisedPersonRepository,
userService,
appDictionaryService,
appSupervisedPersonRealTimeLocationRepository
)
{
_appEarlyWarningRepository = appEarlyWarningRepository;
_appEarlyWarningPushResultRepository = appEarlyWarningPushResultRepository;
_hubContext = hubContext;
_appDeviceManagementRepository = appDeviceManagementRepository;
_appEarlyWarningViewStatisticsRepository = appEarlyWarningViewStatisticsRepository;
_appCommonFenceService = appCommonFenceService;
_appBusinessApplicationRepository = appBusinessApplicationRepository;
_clientNotifyService = clientNotifyService;
_appEarlyWarningRuleRepository = appEarlyWarningRuleRepository;
_appCaseManagementService = appCaseManagementService;
_userService = userService;
}
#endregion Identity
/// <summary>
/// 手动添加预警信息[比如:监管人App聊天窗口调用]
/// </summary>
/// <returns></returns>
/// <remarks>
/// ###### 手动触发
/// 通过移动端监管人APP给被监管人手动录入预警的类型数据
/// </remarks>
public async Task<IResultOutput> ManualAddEarlyWarning(EarlyWarningAddInput input)
{
//[获取当前[被监管挂人员]的案件
var caseInfo = await base.GetCaseInfoBySupervisedPersonId(input.SupervisedPersonId);
if (caseInfo == null) return ResultOutput.NotOk($"当前被监管人:{input.SupervisedPersonId}不存在正在进行的案件!");
//字典
var dictionaryGetOutput = await _appDictionaryService.GetDicByDicId(input.EarlyWarningTypeId);
//公共逻辑
return await EarlyWarningCommLogic(caseInfo, dictionaryGetOutput, null, input.address == null ? "" : input.address);
}
/// <summary>
/// 新增预计信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> AddAsync(AppEarlyWarningAddInput input) =>
await base.AddAsync(input, _appEarlyWarningRepository);
/// <summary>
/// 批量新增预计信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> BatchAddAsync(List<AppEarlyWarningAddInput> input)
{
List<AppEarlyWarningViewStatistics> earlyWarningView = new EditableList<AppEarlyWarningViewStatistics>();
var spIds = input.Select(w => w.SupervisedPersonId).ToList();
var admins = (await _userService.GetAllAdminUserIds()).Select(w => new KeyValueDto()
{
Id = w.Id,
Value = w.UserName,
Text = w.UserName
}).ToList();
var superviseList = (await base.GetSuperviseListByUserId(spIds)).Select(w => new KeyValueDto()
{
Id = w.SupervisedId,
Value = w.SupervisedName,
Text = w.SupervisedName
}).ToList();
foreach (var addInput in input)
{
//管理员
earlyWarningView.AddRange(await AddEarlyWithViews(addInput, admins));
//监管人
earlyWarningView.AddRange(await AddEarlyWithViews(addInput, superviseList));
//被监管人自己
earlyWarningView.AddRange(await AddEarlyWithViews(addInput, new EditableList<KeyValueDto>()
{
new KeyValueDto()
{
Id = addInput.SupervisedPersonId,
Text = addInput.SupervisedPersonName,
Value = addInput.SupervisedPersonName
}
}));
}
//入库
await base.AddAsync(input, _appEarlyWarningRepository);
await _appEarlyWarningViewStatisticsRepository.InsertAsync(earlyWarningView);
return ResultOutput.Ok();
}
/// <summary>
/// 批量新增推送结果
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> BatchAddPushResultAsync(List<AppEarlyWarningPushResultAddInput> input)
{
foreach (var item in input)
{
// item.WarningId = item.Id;
item.Id = null;
}
//入库
await base.AddAsync(input, _appEarlyWarningPushResultRepository);
return ResultOutput.Ok();
}
/// <summary>
/// 根据预计类型枚举和设备唯一标识符新增预警信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <remarks>
/// ###### 设备触发
/// 设备触发设备拆除的预警情况,不需要token鉴权,只需要一个设备唯一码即可
/// </remarks>
[AllowAnonymous]
public async Task<IResultOutput> AddEarlyWarning(AddEarlyWarningInput input)
{
//查找设备
var device =
await _appDeviceManagementRepository.FindAsync(w => w.UniqueIdentifier == input.UniqueIdentifier);
if (device == null) return ResultOutput.NotOk($"当前设备:{input.UniqueIdentifier}不存在!");
//[获取当前[被监管挂人员]的案件
var caseInfo = await base.GetCaseInfoBySupervisedPersonId(device.SupervisedPersonId);
if (caseInfo == null) return ResultOutput.NotOk($"当前设备标识符:{input.UniqueIdentifier}绑定的被监管人不存在!");
//处理预警类型
var dictionaryGetOutput = input.EarlyWarningType switch
{
EarlyWarningTypeEnum.EquipmentRemoval => await base.GetDictionariesOutput("early_warning_type",
"equipmentremoval"),
_ => throw new ArgumentOutOfRangeException()
};
if (dictionaryGetOutput == null)
return ResultOutput.NotOk($"当前预警类型:{input.EarlyWarningType.ToDescription()}不存在字典中,请联系管理员添加");
//公共逻辑
return await EarlyWarningCommLogic(caseInfo, dictionaryGetOutput, device);
}
/// <summary>
/// 查询列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<IResultOutput> GetPageAsync(AppEarlyWarningGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appEarlyWarningRepository.AsQueryable(false, true));
// 先应用案件ID过滤条件
express = express.Where(w => caseIdList.Contains(w.CaseId));
// 然后再获取分页数据
return await base.GetEntityAddPageAsync<AppEarlyWarning, AppEarlyWarningGetPageInput, AppEarlyWarningListDto>(input, express);
}
/// <summary>
/// 越界预警统计查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetCrossborderStatisticsAsync(AppEarlyWarningGetPageInput input)
{ //获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appEarlyWarningRepository.AsQueryable(false, true));
var grudlist = express.Where(p=> caseIds.Contains(p.CaseId))
.WhereIf(input.supname.NotNull(), w => w.SupervisedPersonName.Contains(input.supname))
.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Select(q => new { q.Key.CaseId, q.Key.CaseName, q.Key.SupervisedPersonName, q.Key.SupervisedPersonId, Count = q.ToList().Count() }).Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize);
//var SupervisedPersonIds = grudlist.Select(q => q.SupervisedPersonId);
// var grudlistcunot = express.Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)).ToList();
return ResultOutput.Ok(new { TotalCount = express.Where(p => caseIds.Contains(p.CaseId)).GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Count(), grudlist });
}
/// <summary>
/// 设备上传经纬度时候,验证
/// </summary>
/// <returns></returns>
/// <remarks>
/// ###### 设备上传经纬度时候,验证
/// a)是否脱离监管区域,监管区域以案件设置的围栏为准,这里需要注意一下,如果通过了跨区域的申请,在这个时间内,不做预警触发
/// b)同案人员地点靠经,如果存在2个以上的人员(包括2个),依据最近一次经纬度进行校验,范围为案件申请里面的接近等级
/// </remarks>
[AllowAnonymous]
public async Task<IResultOutput> ValidWithLatitudeAndLongitude(ValidWithLatitudeAndLongitudeInput input)
{
//查找设备
var device = await _appDeviceManagementRepository.FindAsync(w => w.UniqueIdentifier == input.UniqueIdentifier);
if (device == null) return ResultOutput.NotOk($"当前设备:{input.UniqueIdentifier}不存在!");
if (device.DataStatus != DataStatusEnum.Normal) return ResultOutput.Ok();
//[获取当前[被监管挂人员]的案件
var caseInfo = await base.GetCaseInfoBySupervisedPersonId(device.SupervisedPersonId);
return caseInfo == null
? ResultOutput.NotOk($"当前设备标识符:{input.UniqueIdentifier}绑定的被监管人不存在!")
: caseInfo.ApprovalStatus != ApprovalStatusEnum.PassReview
? ResultOutput.Ok()
: await ValidWithLatitudeAndLongitudeCommonLogic(caseInfo, input.Longitude, input.Latitude);
}
/// <summary>
/// 设备上传经纬度时候,验证
/// </summary>
/// <returns></returns>
/// <remarks>
/// ###### 设备上传经纬度时候,验证
/// a)是否脱离监管区域,监管区域以案件设置的围栏为准,这里需要注意一下,如果通过了跨区域的申请,在这个时间内,不做预警触发
/// b)同案人员地点靠经,如果存在2个以上的人员(包括2个),依据最近一次经纬度进行校验,范围为案件申请里面的接近等级
/// </remarks>
public async Task<IResultOutput> ValidWithLatitudeAndLongitude(ValidWithLatitudeAndLongitudeByIdInput input)
{
//[获取当前[被监管挂人员]的案件
var caseInfo = await base.GetCaseInfoBySupervisedPersonId(input.SupervisedPersonId);
if (caseInfo == null) return ResultOutput.NotOk($"当前设备标识符:{input.SupervisedPersonId}绑定的被监管人不存在!");
if (caseInfo.ApprovalStatus != ApprovalStatusEnum.PassReview) return ResultOutput.Ok();
//如果当前设备绑定的设备被禁用
var deviceBind = await _appDeviceManagementRepository.FindAsync(w => w.SupervisedPersonId == caseInfo.SupervisedPersonId);
return deviceBind != null && deviceBind.DataStatus != DataStatusEnum.Normal
? ResultOutput.Ok()
: await ValidWithLatitudeAndLongitudeCommonLogic(caseInfo, input.Longitude, input.Latitude, true);
}
/// <summary>
/// 批量设置是否查阅状态
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> BatchSetCheckStatus(SetCheckStatusInput input)
{
if (_user?.Id > 0 || !input.Ids.Any()) return ResultOutput.Ok();
//查询记录(根据公告Id和订阅者ID(被监管人Id))
var earlyWarnings = await _appEarlyWarningViewStatisticsRepository
.Where(w => input.Ids.Contains(w.AppEarlyWarningId) && w.SubscriberId == User.Id)
.ToListAsync();
earlyWarnings.ForEach(item =>
{
//如果已经是已读了就直接返回
if (item.CheckStatus == CheckStatusEnum.Checked) return;
item!.CheckStatus = input.CheckStatus;
item.CheckTime = input.CheckStatus == CheckStatusEnum.Checked ? DateTime.Now : null;
});
//批量修改
await _appEarlyWarningViewStatisticsRepository.UpdateAsync(earlyWarnings);
return ResultOutput.Ok();
}
/// <summary>
/// 业务工作台==>最新5条预警
/// </summary>
/// <returns></returns>
public async Task<IResultOutput> EarlyWarningBusinessWorkbench()
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Where(w=> w.AppCaseManagement!=null&&caseIdList.Contains(w.AppCaseManagement.Id)).Select(w => w.AppCaseManagement.Id).ToListAsync();
var dataList = await _appEarlyWarningRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.OrderByDescending(w => w.CreatedTime)
.Skip(0)
.Take(5)
.ProjectTo<AppEarlyWarningListDto>(Mapper.ConfigurationProvider)
.ToListAsync();
var dictIds = dataList.Select(w => w.EarlyWarningTypeId).ToList();
var dataDict = await _appDictionaryService.GetDicByDicIds(new BatchIdsInput()
{
Ids = dictIds
});
foreach (var listDto in dataList)
{
listDto.EarlyWarningTypeName = dataDict.FirstOrDefault(w => w.Id == listDto.EarlyWarningTypeId)?.Name;
}
return ResultOutput.Ok(dataList);
}
#region Private
/// <summary>
/// 查询实时预警条件
/// </summary>
/// <param name="pageInput"></param>
/// <param name="query"></param>
/// <returns></returns>
private async Task<IQueryable<AppEarlyWarning>> GetExpression(AppEarlyWarningGetPageInput pageInput, IQueryable<AppEarlyWarning?> query)
{
var limits = User.limits;
var IsAdmin = User.IsAdmin;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.WhereIf((!IsAdmin),w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
query = query.Where(w => caseIds.Contains(w.CaseId))
.WhereIf(pageInput.KeyWord.NotNull(), w => w.Title.Contains(pageInput.KeyWord) || w.CaseName.Contains(pageInput.KeyWord))
.WhereIf(pageInput.casename.NotNull(), w => w.CaseName.Contains(pageInput.casename))
.WhereIf(pageInput.EarlyWarningTypeId.Any(), a => pageInput.EarlyWarningTypeId.Contains(a.EarlyWarningTypeId))
.WhereIf(pageInput.UserSearch != null, p => p.SupervisedPersonId == pageInput.UserSearch!.ModifiedUserId);
var express = base.GetEntityAddExpression<AppEarlyWarning, AppEarlyWarningGetPageInput, long>(pageInput, query);
return express;
}
/// <summary>
/// 添加预警信息公告逻辑发给当前被监管人、管理员、监管人
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="dictionaryGetOutput"></param>
/// <param name="device"></param>
/// <returns></returns>
/// <remarks>
/// 1、如果出现跨区域预警第一次预警后 后面将不在预警 等到回到区域后 再次跨区域 才会出现
/// 2、同案件范围接近报警 也同上 出现第一次后 直到不在出现后 再次出现才报警,如果一直报警 仅为1次
/// </remarks>
private async Task<IResultOutput> EarlyWarningCommLogic(GetCaseInfoBySupervisedPersonIdOutput caseInfo, DictionaryGetOutput dictionaryGetOutput, AppDeviceManagement? device = null, string address = "")
{
//Builder AppEarlyWarning
var entity = await _appEarlyWarningRepository.InsertAsync(new AppEarlyWarning(YitIdHelper.NextId())
{
CaseId = caseInfo.CaseId,
CaseName = caseInfo.CaseName,
Title = dictionaryGetOutput?.Name,
Content = dictionaryGetOutput?.Name + address,
SupervisedPersonId = caseInfo.SupervisedPersonId,
SupervisedPersonName = caseInfo.SupervisedPersonName,
EarlyWarningTypeId = dictionaryGetOutput?.Id,
EarlyWarningTypeName = dictionaryGetOutput?.Name,
DeviceId = device?.Id,
DeviceName = device?.Name,
UniqueIdentifier = device?.UniqueIdentifier
});
var earlyWarningView = await base.GetEarlyWarningRecord(new EditableList<AppEarlyWarningAddInput>()
{
new AppEarlyWarningAddInput(entity.Id)
{
EarlyWarningTypeId = entity.EarlyWarningTypeId,
CaseId = entity.CaseId,
Content = entity.Content,
Title = entity.Title,
SupervisedPersonId = entity.SupervisedPersonId,
SupervisedPersonName = entity.SupervisedPersonName
}
});
await _appEarlyWarningViewStatisticsRepository.InsertAsync(earlyWarningView);
//通知
await _clientNotifyService.RealTimeWarningToPc(new RealTimeWarningToPcInput()
{
AppRemindListDtos = new EditableList<AppRemindListDto>()
{
new AppRemindListDto()
{
Title = entity.Title,
Id = entity.Id,
Content = entity.Content,
CaseId = entity.CaseId,
CreatedTime = entity.CreatedTime
},
},
SubscriberIds = earlyWarningView.Select(w => w.SubscriberId).ToList()
});
return ResultOutput.Ok();
}
/// <summary>
/// 校验当前被监管人位置公共方法
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="isFromPunchRecord">是否来自打卡(打卡的话就不需要判断上一次是否来自围栏内)</param>
/// <returns></returns>
private async Task<IResultOutput> ValidWithLatitudeAndLongitudeCommonLogic(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, bool isFromPunchRecord = false)
{
if (!caseInfo.ElectricFenceId.HasValue) return ResultOutput.Ok();
//[1]跨域申请
var commonFence = (IResultOutput<AppCommonFenceGetDto>)await _appCommonFenceService.GetAsync(caseInfo.ElectricFenceId.Value);
var points = commonFence.Data.Path.StrToLatLngList();
await LeaveArea(caseInfo, longitude, latitude, points, isFromPunchRecord);
//[2]同案人员地点靠近
await InvestigatorsApproach(caseInfo, longitude, latitude, points, isFromPunchRecord);
//[3]
await Getpoi(caseInfo, longitude, latitude, isFromPunchRecord);
return ResultOutput.Ok();
}
/// <summary>
/// 校验当前被监管人位置公共方法 多个监控区域
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task<IResultOutput> ValidWithLatitudeAndLongitudeCommonLogic1(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, bool isFromPunchRecord = false)
{
if (!caseInfo.ElectricFenceId.HasValue) return ResultOutput.Ok();
await LeaveArea1(caseInfo, longitude, latitude, isFromPunchRecord);
//[2]同案人员地点靠近
//await InvestigatorsApproach(caseInfo, longitude, latitude, points, isFromPunchRecord);
return ResultOutput.Ok();
}
/// <summary>
/// 处理预警规则(True需要)
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="dictionaryGet"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task<bool> IsNeedToEarlyWarning(GetCaseInfoBySupervisedPersonIdOutput caseInfo, DictionaryGetOutput dictionaryGet, decimal longitude, decimal latitude, BmapPoint[] bmapPoints, bool isFromPunchRecord = false)
{
var earlyWarningRule = await _appEarlyWarningRuleRepository.FindAsync(w =>
w.EarlyWarningTypeId == dictionaryGet.Id &&
w.SupervisedPersonId == caseInfo.SupervisedPersonId &&
w.CaseId == caseInfo.CaseId);
//判断点是否在多边形内(基本思路是用交点法)(true:在围栏内,false:在围栏外)
var isPointInPolygon = GraphUtils.IsPointInPolygon(new BmapPoint(longitude, latitude), bmapPoints);
//上一次是否在圈内(只针对定位)
var lastIsPointInPolygon = earlyWarningRule?.LastIsPointInPolygon ?? false;
if (earlyWarningRule == null)
{
await _appEarlyWarningRuleRepository.InsertAsync(new AppEarlyWarningRule(YitIdHelper.NextId())
{
CaseId = caseInfo.CaseId,
CaseName = caseInfo.CaseName,
SupervisedPersonId = caseInfo.SupervisedPersonId,
SupervisedPersonName = caseInfo.SupervisedPersonName,
EarlyWarningTypeId = dictionaryGet.Id,
EarlyWarningTypeName = dictionaryGet.Name,
LastIsPointInPolygon = isPointInPolygon
});
}
else
{
earlyWarningRule.LastIsPointInPolygon = isPointInPolygon;
//跟新上一次是否实在围栏内
await _appEarlyWarningRuleRepository.UpdateAsync(earlyWarningRule, UpdatingProps<AppEarlyWarningRule>(x => x.LastIsPointInPolygon)!);
}
//如果来自打卡直接返回
if (isFromPunchRecord) return !isPointInPolygon;
else
{
//预警条件:上一次在圈内且现在在圈外,如果第一次都在外面那么也需要预警
return earlyWarningRule == null && !isPointInPolygon ? true : lastIsPointInPolygon && !isPointInPolygon;
}
}
/// <summary>
/// 处理预警规则(True需要) 多个监控区域
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="dictionaryGet"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task<bool> IsNeedToEarlyWarning1(GetCaseInfoBySupervisedPersonIdOutput caseInfo, DictionaryGetOutput dictionaryGet, decimal longitude, decimal latitude, bool isFromPunchRecord = false)
{
var earlyWarningRule = await _appEarlyWarningRuleRepository.FindAsync(w =>
w.EarlyWarningTypeId == dictionaryGet.Id &&
w.SupervisedPersonId == caseInfo.SupervisedPersonId &&
w.CaseId == caseInfo.CaseId);
//循环监控区域
var isPointInPolygon = false;
foreach (var item in caseInfo.ElectricFenceId.Value.ToString().Split(","))
{
//[1]跨域申请
var commonFence = (IResultOutput<AppCommonFenceGetDto>)await _appCommonFenceService.GetAsync(caseInfo.ElectricFenceId.Value);
var bmap = commonFence.Data.Path.StrToLatLngList();//转换字符串二维数组经纬度
//判断点是否在多边形内(基本思路是用交点法)(true:在围栏内,false:在围栏外)
isPointInPolygon = GraphUtils.IsPointInPolygon(new BmapPoint(longitude, latitude), bmap);
if (isPointInPolygon) break;
}
//上一次是否在圈内(只针对定位)
var lastIsPointInPolygon = earlyWarningRule?.LastIsPointInPolygon ?? false;
if (earlyWarningRule == null)
{
await _appEarlyWarningRuleRepository.InsertAsync(new AppEarlyWarningRule(YitIdHelper.NextId())
{
CaseId = caseInfo.CaseId,
CaseName = caseInfo.CaseName,
SupervisedPersonId = caseInfo.SupervisedPersonId,
SupervisedPersonName = caseInfo.SupervisedPersonName,
EarlyWarningTypeId = dictionaryGet.Id,
EarlyWarningTypeName = dictionaryGet.Name,
LastIsPointInPolygon = isPointInPolygon
});
}
else
{
earlyWarningRule.LastIsPointInPolygon = isPointInPolygon;
//跟新上一次是否实在围栏内
await _appEarlyWarningRuleRepository.UpdateAsync(earlyWarningRule, UpdatingProps<AppEarlyWarningRule>(x => x.LastIsPointInPolygon)!);
}
//如果来自打卡直接返回
if (isFromPunchRecord) return !isPointInPolygon;
else
{
//预警条件:上一次在圈内且现在在圈外,如果第一次都在外面那么也需要预警
return earlyWarningRule == null && !isPointInPolygon ? true : lastIsPointInPolygon && !isPointInPolygon;
}
}
/// <summary>
/// 处理同案件人员靠近
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task InvestigatorsApproach(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, BmapPoint[] bmapPoints, bool isFromPunchRecord)
{
var allInProcessCase = await base._appCaseManagementRepository.AsQueryable(false, true)
.Where(w => w.CaseProgress != CaseProgressEnum.Pending && w.CaseProgress != CaseProgressEnum.Closed && w.Id == caseInfo.CaseId)
.Select(w => w.Id)
.ToListAsync();
//当前被监管人定位信息
var currentSpLocation = await _appSupervisedPersonRealTimeLocationRepository
.AsQueryable(false, true)
.Where(w => allInProcessCase.Contains(w.CaseId) && w.SupervisedPersonId != caseInfo.SupervisedPersonId)
.Select(w => new
{
w.SupervisedPersonId,
w.SupervisedPersonName,
w.Latitude,
w.Longitude,
w.CreatedTime
}).ToListAsync();
var ita = await base.GetDictionariesOutput("early_warning_type", "InvestigatorsApproach");
//规则:设置了接近等级(米)、当前等位信息、需要预警
if (caseInfo.ProximityLevel == default || !currentSpLocation.Any() && !await IsNeedToEarlyWarning(caseInfo, ita, longitude, latitude, bmapPoints, isFromPunchRecord)) return;
{
foreach (var tempDistinct in currentSpLocation.Select(item => GraphUtils.GetDistance(longitude, latitude, item.Longitude, item.Latitude)))
{
//出了电子围栏,添加一条预计信息
if (tempDistinct > (decimal)caseInfo.ProximityLevel || ita == null) continue;
_ = await ManualAddEarlyWarning(new EarlyWarningAddInput()
{
EarlyWarningTypeId = ita.Id,
SupervisedPersonId = caseInfo.SupervisedPersonId
});
break;
}
}
}
/// <summary>
/// 处理脱离围栏
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task LeaveArea(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, BmapPoint[] bmapPoints, bool isFromPunchRecord)
{
//是否脱离监管区域、判断当前监管人是否申请了跨域
var dtNow = DateTime.Now;
//跨域申请字典
var df = await base.GetDictionariesOutput("application_type", "df");
//被监管人职位字典
var spBusApp = await _appBusinessApplicationRepository.AsQueryable(false, true)
.Where(w =>
df != null &&
w.SupervisedPersonId == caseInfo.SupervisedPersonId &&
dtNow >= w.ActiveTimePeriodBegin && dtNow <= w.ActiveTimePeriodEnd &&
w.AuditStatus == AuditStatusEnum.Pass &&
w.ApplicationTypeId == df.Id
).ToListAsync();
//只有有电子围栏且当前时间段没有跨域申请的才判断
var dic = await base.GetDictionariesOutput("early_warning_type", "LeaveArea");
//出了电子围栏,添加一条预计信息
if (caseInfo.ElectricFenceId.HasValue && !spBusApp.Any() && dic != null && await IsNeedToEarlyWarning(caseInfo, dic, longitude, latitude, bmapPoints, isFromPunchRecord))
{
_ = await ManualAddEarlyWarning(new EarlyWarningAddInput()
{
EarlyWarningTypeId = dic.Id,
SupervisedPersonId = caseInfo.SupervisedPersonId
});
}
}
/// <summary>
/// 处理脱离围栏---多个监管区域
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task LeaveArea1(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, bool isFromPunchRecord)
{
//是否脱离监管区域、判断当前监管人是否申请了跨域
var dtNow = DateTime.Now;
//跨域申请字典
var df = await base.GetDictionariesOutput("application_type", "df");
//被监管人职位字典
var spBusApp = await _appBusinessApplicationRepository.AsQueryable(false, true)
.Where(w =>
df != null &&
w.SupervisedPersonId == caseInfo.SupervisedPersonId &&
dtNow >= w.ActiveTimePeriodBegin && dtNow <= w.ActiveTimePeriodEnd &&
w.AuditStatus == AuditStatusEnum.Pass &&
w.ApplicationTypeId == df.Id
).ToListAsync();
//只有有电子围栏且当前时间段没有跨域申请的才判断
var dic = await base.GetDictionariesOutput("early_warning_type", "LeaveArea");
//出了电子围栏,添加一条预计信息
if (caseInfo.ElectricFenceId.HasValue && !spBusApp.Any() && dic != null && await IsNeedToEarlyWarning1(caseInfo, dic, longitude, latitude, isFromPunchRecord))
{
_ = await ManualAddEarlyWarning(new EarlyWarningAddInput()
{
EarlyWarningTypeId = dic.Id,
SupervisedPersonId = caseInfo.SupervisedPersonId
});
}
}
/// <summary>
/// 进入未经许可场所
/// </summary>
/// <param name="caseInfo"></param>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="bmapPoints"></param>
/// <param name="isFromPunchRecord"></param>
/// <returns></returns>
private async Task<bool> Unlicensed(GetCaseInfoBySupervisedPersonIdOutput caseInfo, string name)
{
//停留未许可场所预警
var Unlicensed = await base.GetDictionariesOutput("early_warning_type", "Unlicensed");
var earlyWarningRule = await _appEarlyWarningRuleRepository.FindAsync(w =>
w.EarlyWarningTypeId == Unlicensed.Id &&
w.SupervisedPersonId == caseInfo.SupervisedPersonId &&
w.CaseId == caseInfo.CaseId);
var isPointInPolygon = false;
if (earlyWarningRule == null)
{
//LastIsPointInPolygon=true当前被监管人在未经允许的地方 false不在未经允许的地方
await _appEarlyWarningRuleRepository.InsertAsync(new AppEarlyWarningRule(YitIdHelper.NextId())
{
CaseId = caseInfo.CaseId,
CaseName = caseInfo.CaseName,
SupervisedPersonId = caseInfo.SupervisedPersonId,
SupervisedPersonName = caseInfo.SupervisedPersonName,
EarlyWarningTypeId = Unlicensed.Id,
EarlyWarningTypeName = Unlicensed.Name + $"+{name}",
LastIsPointInPolygon = false
});
}
else
{
if (!earlyWarningRule.EarlyWarningTypeName.Contains(name))
{
earlyWarningRule.EarlyWarningTypeName = Unlicensed.Name + $"+{name}";
//更新上一次是否是在该地方停留
await _appEarlyWarningRuleRepository.UpdateAsync(earlyWarningRule, UpdatingProps<AppEarlyWarningRule>(x => x.LastIsPointInPolygon)!);
}
else
{
earlyWarningRule.EarlyWarningTypeName = Unlicensed.Name + $"+{name}";
isPointInPolygon = true;
}
}
return isPointInPolygon;
}
/// <summary>
/// 添加预警和查看预警方法
/// </summary>
/// <param name="addInput"></param>
/// <param name="dtos"></param>
/// <returns></returns>
private async Task<List<AppEarlyWarningViewStatistics>> AddEarlyWithViews(AppEarlyWarningAddInput addInput, List<KeyValueDto> dtos)
{
return dtos.Select(w => new AppEarlyWarningViewStatistics(YitIdHelper.NextId())
{
SupervisedName = w.Value,
SubscriberId = w.Id,
CaseId = addInput.CaseId,
AppEarlyWarningId = addInput.Id ?? default
}).ToList();
}
/// <summary>
/// 通过经纬度 获取poi
/// </summary>
/// <returns></returns>
/// <remarks>
/// </remarks>
public async Task Getpoi(GetCaseInfoBySupervisedPersonIdOutput caseInfo, decimal longitude, decimal latitude, bool isFromPunchRecord)
{
if (!string.IsNullOrEmpty(caseInfo.poitypename) && caseInfo.radius > 0 && caseInfo.rice > 0)
{
//未许可场所预警
var Unlicensedtype = await base.GetDictionariesOutput("early_warning_type", "Unlicensed");
//通过字典获取地图key 密钥
var key = await base.GetDictionariesOutput("map_key", "map_key");
if (key == null) return;
//获取被监管人当前位置的周边位置
var url = $"https://restapi.amap.com/v3/place/around?key={key.Value}&location={longitude},{latitude}&keywords={caseInfo.poitypename.Replace(",", "|")}&radius={caseInfo.radius}&offset=1000&page=1&extensions=all";
string requestString = "";
try
{
Encoding myEncoding = Encoding.UTF8;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.ContentType = "text/plain";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader responseStream = new StreamReader(response.GetResponseStream(), myEncoding);
requestString = responseStream.ReadToEnd();
var da = JsonConvert.DeserializeObject<dynamic>(requestString);//对象集合 requestString
if (da.info == "OK")
{
//判断当前人所在位置是否存在未经许可长时间停留
List<suggestion> list = JsonConvert.DeserializeObject<List<suggestion>>(da.pois + "");
var dalist = list.Where(q => q.distance.ToInt() <= caseInfo.rice);
var name = dalist.OrderBy(q => q.distance.ToInt()).First()?.name;
//长时间停留在未经许可的地方,添加一条预计信息
if (await Unlicensed(caseInfo, name))
{
_ = await ManualAddEarlyWarning(new EarlyWarningAddInput()
{
EarlyWarningTypeId = Unlicensedtype.Id,
SupervisedPersonId = caseInfo.SupervisedPersonId,
address = name
});
}
}
response.Close();
responseStream.Close();
}
catch (Exception)
{
}
}
}
#endregion Private
/// <summary>
/// 根据时间范围查询预警信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetEarlyWarningByTimeRangeAsync(AppEarlyWarningTimeRangeInput input)
{
// 1. 验证时间范围不能为空
if (input.TimeSearch == null || input.TimeSearch.BeginTime == null || input.TimeSearch.EndTime == null)
{
return ResultOutput.NotOk("开始时间和结束时间不能为空");
}
// 2. 确保开始时间不晚于结束时间
if (input.TimeSearch.BeginTime > input.TimeSearch.EndTime)
{
return ResultOutput.NotOk("开始时间不能晚于结束时间");
}
// 3. 验证时间范围不能超过半年(183天)
TimeSpan timeDiff = input.TimeSearch.EndTime.Value - input.TimeSearch.BeginTime.Value;
if (timeDiff.TotalDays > 183)
{
return ResultOutput.NotOk("查询时间范围不能超过半年");
}
// 4. 获取当前用户有权限的案件ID列表
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
// 5. 构建查询表达式
var beginTime = input.TimeSearch.BeginTime.Value;
var endTime = input.TimeSearch.EndTime.Value;
var query = _appEarlyWarningRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.Where(w => w.CreatedTime >= beginTime && w.CreatedTime <= endTime);
// 6. 获取总数
var total = query.Count();
// 7. 分页查询
var items = await query
.OrderByDescending(w => w.CreatedTime)
.ProjectTo<AppEarlyWarningPushDto>(Mapper.ConfigurationProvider)
.ToListAsync();
//8 补全监管人、监管人id、监管人手机号
var caseIdList = items.Select(w => w.CaseId).Distinct().ToList();
//9 根据案件ID查询监管人(可能多条)
var dataCaseSupervise = await _appCaseManagementService.GetSupervisedPageAsync(new GetSuperviseorPage() { Ids = caseIdList });
//10 构建「案件ID → 该案件的所有监管人列表」的映射
var caseSupervisorMap = dataCaseSupervise
.GroupBy(x => x.CaseId) // 按案件ID分组
.ToDictionary(g => g.Key, g => g.ToList()); // 分组结果转字典
var supervisorIdList = dataCaseSupervise.Select(w => w.SupervisorId).Distinct().ToList();
//11 根据监管人ID查询电话
var user = await _userService.GetAllByConditionAsync(new BatchIdsInput() { Ids = supervisorIdList });
//12 构建「监管人ID → 电话」的映射
var supervisorPhoneMap = user
.ToDictionary(u => u.Id, u => u.Phone); // 监管人ID为Key,电话为Value
// 生成新的案件列表(每个案件对应所有监管人)
var newItems = new List<AppEarlyWarningPushDto>();
//13 脱离区域申请
var Unlicensedtype = await base.GetDictionariesOutput("early_warning_type", "LeaveAreaApplication");
//循环插入预警信息
foreach (var item in items)
{
var caseId = item.CaseId;
// 若该案件有监管人,遍历所有监管人生成新项
if (caseSupervisorMap.TryGetValue(caseId, out var supervisors))
{
foreach (var supervisor in supervisors)
{
// 复制原案件信息(可通过 AutoMapper 简化,见下文)
var newItem = new AppEarlyWarningPushDto();
newItem.Id = item.Id;
newItem.CaseId = item.CaseId;
newItem.CaseName = item.CaseName;
newItem.Content = item.Content;
newItem.UniqueIdentifier = item.UniqueIdentifier;
newItem.DeviceId = item.DeviceId;
newItem.DeviceName = item.DeviceName;
newItem.EarlyWarningTypeId = item.EarlyWarningTypeId;
newItem.EarlyWarningTypeName = item.EarlyWarningTypeName;
newItem.Title = item.Title;
newItem.CreatedTime = item.CreatedTime;
newItem.SupervisedPersonId = item.SupervisedPersonId;
newItem.SupervisedPersonName = item.SupervisedPersonName;
// 填充监管人字段
newItem.SupervisorName = supervisor.SupervisorName;
newItem.SupervisorId = supervisor.SupervisorId;
newItem.BeginTime = beginTime;
newItem.EndTime = endTime;
// 从电话映射中获取监管人电话(处理空值)
newItem.Phone = supervisorPhoneMap.TryGetValue(supervisor.SupervisorId, out var phone)
? phone
: string.Empty;
//判断是否已经推送过
var pushList = await _appEarlyWarningPushResultRepository.AsQueryable(false, true)
.Where(w => w.WarningId == newItem.Id && w.SupervisorId == supervisor.SupervisorId)
.ProjectTo<AppEarlyWarningPushResultAddInput>(Mapper.ConfigurationProvider)
.ToListAsync()
.ConfigureAwait(false);
newItem.PushFlag = pushList.Count > 0 ? "1" : "0";
newItems.Add(newItem);
}
}
}
//14 获取未处理的申请信息
var spBusApplication = await _appBusinessApplicationRepository.AsQueryable(false, true).Where(w => w.AuditStatus == AuditStatusEnum.PendingReview).ToListAsync();
if (spBusApplication.Count > 0)
{
//8 补全监管人、监管人id、监管人手机号
var busCaseIdList = spBusApplication.Select(w => w.CaseId).Distinct().ToList();
//根据案件ID查询监管人(可能多条)
dataCaseSupervise.Clear();
dataCaseSupervise = await _appCaseManagementService.GetSupervisedPageAsync(new GetSuperviseorPage() { Ids = busCaseIdList });
// 构建「案件ID → 该案件的所有监管人列表」的映射
caseSupervisorMap.Clear();
caseSupervisorMap = dataCaseSupervise
.GroupBy(x => x.CaseId) // 按案件ID分组
.ToDictionary(g => g.Key, g => g.ToList()); // 分组结果转字典
supervisorIdList.Clear();
supervisorIdList = dataCaseSupervise.Select(w => w.SupervisorId).Distinct().ToList();
// 根据监管人ID查询电话
user.Clear();
user = await _userService.GetAllByConditionAsync(new BatchIdsInput() { Ids = supervisorIdList });
// 构建「监管人ID → 电话」的映射
supervisorPhoneMap.Clear();
supervisorPhoneMap = user
.ToDictionary(u => u.Id, u => u.Phone); // 监管人ID为Key,电话为Value
// 生成新的案件列表(每个案件对应所有监管人)
foreach (var item in spBusApplication)
{
var caseId = item.CaseId;
// 若该案件有监管人,遍历所有监管人生成新项
if (caseSupervisorMap.TryGetValue(caseId, out var supervisors))
{
foreach (var supervisor in supervisors)
{
// 复制原案件信息(可通过 AutoMapper 简化,见下文)
var newItem = new AppEarlyWarningPushDto();
newItem.SupervisedPersonId = item.SupervisedPersonId;
newItem.SupervisedPersonName = item.SupervisedPersonName;
newItem.Content = item.ApplicationDescription;
newItem.EarlyWarningTypeId = Unlicensedtype.Id;
newItem.CaseId = item.CaseId;
newItem.CreatedTime = item.CreatedTime;
newItem.Id = item.Id;
// 填充监管人字段
newItem.SupervisorName = supervisor.SupervisorName;
newItem.SupervisorId = supervisor.SupervisorId;
newItem.BeginTime = beginTime;
newItem.EndTime = endTime;
// 从电话映射中获取监管人电话(处理空值)
newItem.Phone = supervisorPhoneMap.TryGetValue(supervisor.SupervisorId, out var phone)
? phone
: string.Empty;
//判断是否已经推送过
var pushList = await _appEarlyWarningPushResultRepository.AsQueryable(false, true)
.Where(w => w.WarningId == item.Id && w.SupervisorId == supervisor.SupervisorId)
.ProjectTo<AppEarlyWarningPushResultAddInput>(Mapper.ConfigurationProvider)
.ToListAsync()
.ConfigureAwait(false);
newItem.PushFlag = pushList.Count > 0 ? "1" : "0";
newItems.Add(newItem);
}
}
}
}
//15 补充预警类型名称
var dictIds = newItems.Select(w => w.EarlyWarningTypeId).ToList();
var dataDict = await _appDictionaryService.GetDicByDicIds(new BatchIdsInput() { Ids = dictIds });
foreach (var item in newItems)
{
item.EarlyWarningTypeName = dataDict.FirstOrDefault(w => w.Id == item.EarlyWarningTypeId)?.Name;
}
return ResultOutput.Ok(new PagedList<AppEarlyWarningPushDto>()
{
Data = newItems,
TotalCount = newItems.Count, // 展开后的总记录数
PageIndex = input.PageIndex,
PageSize = input.PageSize
});
}
}
/// <summary>
/// poi model
/// </summary>
public class suggestion
{
//类型
public string type { set; get; }
//名称
public string name { set; get; }
//详细地址
public string address { set; get; }
//距离
public string distance { set; get; }
}
}