|
|
|
|
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; }
|
|
|
|
|
}
|
|
|
|
|
}
|