非羁押人员管理平台
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.
 
 

753 lines
39 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.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings.Input;
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;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Output;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Business.EarlyWarning;
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.UnifiedResults;
using ATS.NonCustodial.Shared.Configurations.Options;
using ATS.NonCustodial.Shared.Extensions;
using ATS.NonCustodial.Shared.Extensions.Collection;
using AutoMapper.QueryableExtensions;
using Castle.Components.DictionaryAdapter;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Dynamic;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Business
{
/// <summary>
/// 打卡记录管理
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-06-06 02:56 PM
[DynamicApi(Area = "admin")]
public class AppPunchRecordService : AdminCommonService, IAppPunchRecordService, IDynamicApi
{
#region Identity
private readonly IEfRepository<AppPunchRecordStatistics, long> _appPunchRecordStatisticsRepository;
private readonly IAppCaseManagementService _appCaseManagementService;
private readonly IClientNotifyService _clientNotifyService;
private readonly IAppEarlyWarningService _earlyWarningService;
private readonly IEfRepository<AppUser, long> _appuserRepository;
private readonly IEfRepository<AppEarlyWarning, long> _appEarlyWarningRepository;
private readonly IEfRepository<appauditrecords, long> _appauditrecordsRepository;
private readonly IEfRepository<AppUser, long> _appUserRepository;
private readonly ISMSService _smsService;
public AppPunchRecordService(IEfRepository<AppPunchRecordStatistics, long> appPunchRecordStatisticsRepository,
IAppCaseManagementService appCaseManagementService,
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisedPerson, long> appCaseSupervisedPersonRepository,
IClientNotifyService clientNotifyService,
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository,
IUserService userService,
IAppDictionaryService appDictionaryService,
IEfRepository<AppUser, long> appUserRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> asprl,
IEfRepository<AppUser, long> appuserRepository,
IAppEarlyWarningService appEarlyWarningService, IEfRepository<appauditrecords, long> appauditrecords,
IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
ISMSService smsService)
: base(
appCaseManagementRepository,
appCaseSupervisorRepository,
appCaseSupervisedPersonRepository,
userService,
appDictionaryService,
asprl)
{
_appPunchRecordStatisticsRepository = appPunchRecordStatisticsRepository;
_appCaseManagementService = appCaseManagementService;
_clientNotifyService = clientNotifyService;
_earlyWarningService = appEarlyWarningService;
_appEarlyWarningRepository = appEarlyWarningRepository;
_appauditrecordsRepository = appauditrecords;
_appuserRepository = appuserRepository;
_smsService = smsService;
_appUserRepository = appUserRepository;
}
#endregion Identity
/// <summary>
/// 根据被监管人员Id分页查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetPageAsync(AppPunchRecordGetPageInput input)
{
var data = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == input.Id && w.SupervisedPersonId == input.SupervisedPersonId)
.OrderByDescending(r => r.CreatedTime)
.ProjectTo<AppPunchRecordListDto>(Mapper.ConfigurationProvider)
.PagedAsync(input)
.ConfigureAwait(false);
return ResultOutput.Ok(data);
}
/// <summary>
/// 获取当前打卡时间
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<IResultOutput> GetdkPageAsync(long CaseId, long SupervisedPersonId, string times)
{
var time = "";
var mis = await base.GetDictionariesOutput("plan_time", "interval");//获取打卡时间区间分钟
//获取打卡时间
var data = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == CaseId && w.SupervisedPersonId == SupervisedPersonId)
.OrderByDescending(r => r.CreatedTime).ToListAsync();
if (data.Count > 0)
{
var datime = data.ToList().First().CreatedTime.Value.ToString("yyyy-MM-dd");
//筛选打卡时间过后的后续时间显示
if (datime == DateTime.Now.ToString("yyyy-MM-dd"))
{
foreach (var item in times.Split(','))
{
var st = $"{DateTime.Now.ToString("yyyy-MM-dd")} {item}".ToDateTime().AddMinutes(-mis.Value.ToInt());
var et = $"{DateTime.Now.ToString("yyyy-MM-dd")} {item}".ToDateTime();
if (data.ToList().First().CreatedTime.ToString("yyyy-MM-dd HH:mm").ToDateTime() >= st && data.First().CreatedTime.ToString("yyyy-MM-dd HH:mm").ToDateTime() <= et)
{
var ce = "";
}
else if (et > DateTime.Now.ToString("yyyy-MM-dd HH:mm").ToDateTime())
{
time += $"{item},";
}
}
}
else
{
foreach (var item in times.Split(','))
{
var st = $"{DateTime.Now.ToString("yyyy-MM-dd")} {item}".ToDateTime();
if (st > DateTime.Now.ToString("yyyy-MM-dd HH:mm").ToDateTime())
{
time += $"{item},";
}
}
}
}
else
{
foreach (var item in times.Split(','))
{
var st = $"{DateTime.Now.ToString("yyyy-MM-dd")} {item}".ToDateTime();
if (st > DateTime.Now.ToString("yyyy-MM-dd HH:mm").ToDateTime())
{
time += $"{item},";
}
}
}
return ResultOutput.Ok(time.Trim(','));
}
/// <summary>
/// 获取打卡记录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetPunchPageAsync(AppPunchRecordGetPageInput 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 caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//var list= await base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q=> caseIds.Contains(q.CaseId)).ToListAsync();
var data = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.WhereIf(!string.IsNullOrEmpty(input.name), q => q.SupervisedPersonName.Contains(input.name))
.OrderByDescending(r => r.CreatedTime)
.ProjectTo<AppPunchRecordListDto>(Mapper.ConfigurationProvider)
.PagedAsync(input)
.ConfigureAwait(false);
return ResultOutput.Ok(data);
}
/// <summary>
/// 添加打卡记录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> AddAsync(AppPunchRecordAddInput input)
{
input.PunchVideo = input.PunchVideo?.Replace("\\", "/");
input.PunchVideo = input.PunchVideo.Substring(input.PunchVideo.LastIndexOf("/upload/admin"));
//就是那个傻逼App开发人员啥都不想传
var entity = Mapper.Map<AppPunchRecordStatistics>(input);
//[获取当前[被监管挂人员]的案件
var caseInfo = await _appCaseManagementService.GetCaseInfoBySupervisedPersonId();
if (caseInfo == null) return ResultOutput.NotOk($"打卡失败,当前被监管人:{User.Name}不存在正在进行的案件!");
entity.CaseId = caseInfo.CaseId;
entity.CaseName = caseInfo.CaseName;
entity.SupervisedPersonId = caseInfo.SupervisedPersonId;
entity.SupervisedPersonName = caseInfo.SupervisedPersonName;
await _appPunchRecordStatisticsRepository.InsertAsync(entity);
#region 每次打卡成功,清空未打卡记录次数
var person = await _appSupervisedPersonRepository.AsQueryable(false, true).Where(w => w.CaseId == caseInfo.CaseId && w.SupervisedPersonId == caseInfo.SupervisedPersonId).ToListAsync();
if (person.Count > 0)
{
person.FirstOrDefault().AttendanceRecord = 0;
await _appSupervisedPersonRepository.UpdateAsync(person);
}
#endregion
#region 打卡消息推送手机通知栏
//被监管人id
var list = new List<long>();
list.Add(entity.SupervisedPersonId);
//监管人ids
var SupervisedIds = new List<long>();
//获取当前被监管人的监管人员id
(await GetSuperviseListByUserId(list)).ForEach(q =>
{
SupervisedIds.Add(q.SupervisedId);
});
//获取监管人手机唯一id
var supervisecids = _appuserRepository.AsQueryable(false, true).ToList().Where(q => SupervisedIds.Contains(q.Id));
if (supervisecids.Where(q => !string.IsNullOrEmpty(q.CId)).Count() > 0)
{
try
{
//获取个推配置
var TweetConfig = LazyGetRequiredService<TweetsConfigConfiguration>();
//查询判断token是否存在 存在直接获取 不存在通过接口重新获取token
var token = Cache.Exists("token");
if (!token)
base.GettoekenQuery();
var tokenstr = Cache.Get("token");
var msg_list = new List<dynamic>();
foreach (var item in supervisecids.Where(q => !string.IsNullOrEmpty(q.CId)))
{
//随机生成数
var request_id = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 32).ToString();
msg_list.Add(new
{
request_id = request_id,
settings = new { ttl = 7200000 },
audience = new { cid = item.CId.ToString().Split(",") },
push_message = new
{
notification = new
{
title = "非羁押",
body = $"{entity.SupervisedPersonName}位于{entity.CheckInLocation}-打卡成功",
click_type = "none",
}
}
});
}
var data = new
{
is_async = true,
msg_list = msg_list
};
//打卡消息推送被监管人手机通知栏
var re = base.GetpostQuery($"{TweetConfig.BaseUrl.Replace("$appId", TweetConfig.AppID)}{TweetConfig.cidurl}", data, tokenstr);
}
catch (Exception ex)
{
}
}
#endregion
//将定位信息添加到定位表
await _appSupervisedPersonRealTimeLocationRepository.InsertAsync(new AppSupervisedPersonRealTimeLocation(Yitter.IdGenerator.YitIdHelper.NextId())
{
CaseId = caseInfo.CaseId,
CaseName = caseInfo.CaseName,
SupervisedPersonId = caseInfo.SupervisedPersonId,
SupervisedPersonName = caseInfo.SupervisedPersonName,
Place = input.CheckInLocation,
Longitude = input.Longitude,
Latitude = input.Latitude
});
//校验是否违规
await _earlyWarningService.ValidWithLatitudeAndLongitude(new ValidWithLatitudeAndLongitudeByIdInput()
{
SupervisedPersonId = caseInfo.SupervisedPersonId,
Latitude = input.Latitude,
Longitude = input.Longitude
});
return ResultOutput.Result(entity.Id > 0);
}
/// <summary>
/// 打卡记录统计分页查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> PunchRecordStatisticsPageAsync(PunchRecordStatisticalPageInput input)
{
// <summary>
// 统计时间
// </summary>
// <remarks>
// 日:2022-05-03
// 周:2022-05-23~05-29
// 月:2022-05
// </remarks>
var startTime = DateTime.MinValue;
var endTime = DateTime.MinValue;
switch (input.DateStatisticalDimension)
{
case DateStatisticalDimensionEnum.Day when DateTime.TryParse(input.StatisticalTime, out startTime):
endTime = startTime.AddDays(1);
break;
case DateStatisticalDimensionEnum.Week:
{
var tempDate = input.StatisticalTime?.Split("-");
if (tempDate!.Length == 2 && DateTime.TryParse(tempDate[0], out startTime) && DateTime.TryParse(tempDate[1], out endTime)) endTime.AddDays(1);
break;
}
case DateStatisticalDimensionEnum.Mouth when DateTime.TryParse(input.StatisticalTime, out startTime):
startTime = new DateTime(startTime.Year, startTime.Month, 1);
endTime = startTime.AddMonths(1).AddDays(-1);
break;
case null:
break;
}
//获取当前用户权限下的案件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 spList = await base.GetCurrentUserCaseListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null && caseIdList.Contains(q.AppCaseSupervisedPerson.CaseId)).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
//查询记录
var query = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true).Where(q => spIds.Contains(q.SupervisedPersonId) && caseIdList.Contains(q.CaseId))
.WhereIf(input.CaseId != default, a => a.CaseId == input.CaseId)
.WhereIf(input.SupervisedPersonId != default, w => w.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(startTime != DateTime.MinValue, w => w.CreatedTime >= startTime)
.WhereIf(endTime != DateTime.MinValue, w => w.CreatedTime < endTime)
.ToListAsync();
//分组
var dataGroup = query
.GroupBy(w => new { w.CaseId, w.SupervisedPersonId, w.CaseName, w.SupervisedPersonName });
var pageData = dataGroup
.Skip((input.PageIndex - 1) * input.PageSize)
.Take(input.PageSize);
var dataList = pageData.Select(data => new PunchRecordStatisticsListDto()
{
CaseId = data.Key.CaseId,
SupervisedPersonId = data.Key.SupervisedPersonId,
CaseName = data.Key.CaseName,
SupervisedPersonName = data.Key.SupervisedPersonName,
PunchTimes = data.Count()
}).ToList();
//处理身份证字段
var userList = await _userService.GetAllByConditionAsync(new BatchIdsInput()
{
Ids = dataList.Select(w => w.SupervisedPersonId).ToList()
});
dataList.ForEach(item =>
{
item.IdCard = userList.FirstOrDefault(w => w.Id == item.SupervisedPersonId)?.IdCard;
});
var pageResult = new PagedList<PunchRecordStatisticsListDto>()
{
TotalCount = dataGroup.Count(),
Data = dataList
};
return ResultOutput.Ok(pageResult);
}
/// <summary>
/// Job定时去检查是否有人未打卡------频次打卡
/// </summary>
/// <returns></returns>
[HttpGet, AllowAnonymous]
public async Task<IResultOutput> CheckPunchRecordForJob1()
{
var limits = User.limits;
//[1]获取所有正在执行中的被监管人案件
var allCaseList = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join csr in _appCaseSupervisorRepository.AsQueryable(false, true) on c.Id equals csr.CaseId
join cspr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals cspr.CaseId
where c.CaseProgress != CaseProgressEnum.Pending && c.CaseProgress != CaseProgressEnum.Closed && limits.Contains((char)csr.UnitId)
select new CheckPunchRecordForJobOutput()
{
CaseId = c.Id,
CaseName = c.Name,
CaseBeginTime = c.CaseBeginTime,
CheckInFrequency = c.CheckInFrequency,
RestBeginTime = c.RestBeginTime,
RestEndTime = c.RestEndTime,
SupervisedPersonId = cspr.SupervisedPersonId,
SupervisedPersonName = cspr.SupervisedPersonName,
SupervisorId = csr.SupervisorId,
SupervisorName = csr.SupervisorName
}).ToListAsync();
//去重
allCaseList = allCaseList.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId).ToList();
var casePunchRecordGroup = allCaseList
.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId)
.GroupBy(w => new { w.CheckInFrequency });
//提醒列表
List<AppRemindListDto> appRemindList = new EditableList<AppRemindListDto>();
var dict = await base.GetDictionariesOutput("early_warning_type", "notClocked");
//[2]根据打卡频次,来计算被监管人员是否已打卡
foreach (var cprg in casePunchRecordGroup)
{
//当前案件列表
foreach (var recordForJobOutput in cprg.ToList())
{
//首先判断当前人当前案件是否有预警信息,如果有那么CaseBeginTime应该从最后一次预警时间开始
var lastEarlyWaringPunched = await _appEarlyWarningRepository
.Where(w => w.CaseId == recordForJobOutput.CaseId && w.SupervisedPersonId == recordForJobOutput.SupervisedPersonId && w.EarlyWarningTypeId == dict.Id)
.OrderByDescending(w => w.CreatedTime)
.FirstOrDefaultAsync();
var punchedTime = recordForJobOutput.CaseBeginTime;
if (lastEarlyWaringPunched != null) punchedTime = MidStrEx(lastEarlyWaringPunched?.Content ?? "", "[", "]", punchedTime);
var tempShouldPunchTimeList = DateTimeExtension.CalculatePunchTimePeriod(
punchedTime,
recordForJobOutput.RestBeginTime,
recordForJobOutput.RestEndTime,
recordForJobOutput.CheckInFrequency).Where(w => w <= DateTime.Now);
//查询打卡记录里面有没有对应的时刻的打卡记录
var punchRecordList = await _appPunchRecordStatisticsRepository.AsQueryable(false, true)
.Where(w =>
w.CaseId == recordForJobOutput.CaseId &&
w.SupervisedPersonId == recordForJobOutput.SupervisedPersonId)
.ToListAsync();
appRemindList.AddRange(from punchTime in tempShouldPunchTimeList
where punchRecordList.Any(w => w.CreatedTime != punchTime)
select new AppRemindListDto()
{
Title = "未打卡",
Content = $"{recordForJobOutput.SupervisedPersonName}的案件({recordForJobOutput.CaseName})在时间点:[{punchTime}]未打卡",
CheckStatus = CheckStatusEnum.NotChecked,
CreatedUserId = recordForJobOutput.SupervisedPersonId,
CreatedTime = DateTime.Now,
SupervisedPersonId = recordForJobOutput.SupervisedPersonId,
SupervisedPersonName = recordForJobOutput.SupervisedPersonName,
SupervisorId = recordForJobOutput.SupervisorId,
SupervisorName = recordForJobOutput.SupervisorName,
CaseId = recordForJobOutput.CaseId
});
}
}
//如果有提醒
if (!appRemindList.Any()) return ResultOutput.Ok();
{
//添加到预警表
var earlyEntities = appRemindList.Select(w => new AppEarlyWarningAddInput(YitIdHelper.NextId())
{
Title = dict == null ? "" : dict.Name,
CaseId = w.CaseId.Value,
Content = w.Content,
EarlyWarningTypeId = dict?.Id ?? default,
SupervisedPersonId = w.SupervisedPersonId,
SupervisedPersonName = w.SupervisedPersonName,
}).ToList();
//如果添加了未打卡时间段的记录就不添加了
var earlyWarningIds = earlyEntities.Select(w => w.EarlyWarningTypeId).ToList();
var earlyWarningCaseIds = earlyEntities.Select(w => w.CaseId).ToList();
var earlyWarningSupervisedPersonIds = earlyEntities.Select(w => w.SupervisedPersonId).ToList();
var alreadyEarlyWarning = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => earlyWarningIds.Contains(w.EarlyWarningTypeId) && earlyWarningCaseIds.Contains(w.CaseId) && earlyWarningSupervisedPersonIds.Contains(w.SupervisedPersonId))
.ToListAsync();
//去掉已经存在的
earlyEntities = earlyEntities.Where(earlyEntity =>
!alreadyEarlyWarning.Exists(w =>
w.EarlyWarningTypeId == earlyEntity.EarlyWarningTypeId &&
w.CaseId == earlyEntity.CaseId &&
w.SupervisedPersonId == earlyEntity.SupervisedPersonId &&
earlyEntity.Content!.Contains(w.Content))).ToList();
await _earlyWarningService.BatchAddAsync(earlyEntities);
//根据当前被监管人员的预警信息,计算出应该被通知的人员(被监管人员自己、监管人、管理员)
var earlyWarningRecord = await base.GetEarlyWarningRecord(earlyEntities);
//signalR通知
await _clientNotifyService.RealTimeWarningToPc(new RealTimeWarningToPcInput()
{
AppRemindListDtos = appRemindList,
SubscriberIds = earlyWarningRecord.Select(w => w.SubscriberId).ToList()
});
}
//返回
return ResultOutput.Ok();
}
/// <summary>
/// Job定时去检查是否有人未打卡 ----规定时间打卡
/// </summary>
/// <returns></returns>
[HttpGet, AllowAnonymous]
public async Task<IResultOutput> CheckPunchRecordForJob()
{
// var limits = User.limits;
//[1]获取所有正在执行中的被监管人案件
var allCaseList = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join csr in _appCaseSupervisorRepository.AsQueryable(false, true) on c.Id equals csr.CaseId
join cspr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals cspr.CaseId
where c.CaseProgress != CaseProgressEnum.Pending && c.CaseProgress != CaseProgressEnum.Closed && cspr.ApprovalStatus == ApprovalStatusEnum.PassReview
select new CheckPunchRecordForJobOutput()
{
CaseId = c.Id,
CaseName = c.Name,
CaseBeginTime = c.CaseBeginTime,
CheckInFrequency = c.CheckInFrequency,
RestBeginTime = c.RestBeginTime,
RestEndTime = c.RestEndTime,
SupervisedPersonId = cspr.SupervisedPersonId,
SupervisedPersonName = cspr.SupervisedPersonName,
SupervisorId = csr.SupervisorId,
SupervisorName = csr.SupervisorName,
TimedClock = c.TimedClock
}).ToListAsync();
//去重
allCaseList = allCaseList.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId).ToList();
//提醒列表
List<AppRemindListDto> appRemindList = new EditableList<AppRemindListDto>();
var dict = await base.GetDictionariesOutput("early_warning_type", "notClocked");
var mis = await base.GetDictionariesOutput("plan_time", "interval");//获取打卡时间区间分钟
//循环判断判断是否按规定时间打卡
foreach (var item in allCaseList)
{
//查询被监管人最新审核时间
var appauditrecords = _appauditrecordsRepository.AsQueryable(false, true).Where(q => q.SupervisedPersonId == item.SupervisedPersonId).ToList();
if (appauditrecords.Count() == 0)
continue;
var appauditrecordsdata = appauditrecords.OrderByDescending(q => q.CreatedTime).First();
if (string.IsNullOrEmpty(item.TimedClock)) continue;
foreach (var datehh in item.TimedClock.Split(","))
{
//判断当前时间是否大于打卡时间
var dqdatetime = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}".ToDateTime();
var datetime = $"{DateTime.Now.ToString("yyyy-MM-dd")} {datehh}".ToDateTime();
//通过审核时间去判断打卡提醒
if (appauditrecordsdata != null)
if (datetime < appauditrecordsdata.recordstime)
continue;
if (dqdatetime > datetime)
{
//首先判断当前人当前案件是否有预警信息,如果有那么CaseBeginTime应该从最后一次预警时间开始
var lastEarlyWaringPunched = await _appEarlyWarningRepository
.Where(w => w.CaseId == item.CaseId && w.SupervisedPersonId == item.SupervisedPersonId && w.EarlyWarningTypeId == dict.Id).ToListAsync();
try
{
//查询打卡记录里面有没有对应的时刻的打卡记录
var punchRecordList = await _appPunchRecordStatisticsRepository.AsQueryable(false, true)
.Where(w =>
w.CaseId == item.CaseId &&
w.SupervisedPersonId == item.SupervisedPersonId)
.ToListAsync();
//punchRecordList = punchRecordList.Where(w => $"{w.CreatedTime.ToString("yyyy-MM-dd HH:mm")}" == $"{DateTime.Now.ToString("yyyy-MM-dd")} {datehh}").ToList();
punchRecordList = punchRecordList.Where(w => $"{w.CreatedTime.ToString("yyyy-MM-dd HH:mm")}".ToDateTime() >= $"{DateTime.Now.ToString("yyyy-MM-dd")} {datehh}".ToDateTime().AddMinutes(-mis.Value.ToInt()) && $"{w.CreatedTime.ToString("yyyy-MM-dd HH:mm")}".ToDateTime() <= $"{DateTime.Now.ToString("yyyy-MM-dd")} {datehh}".ToDateTime()).ToList();
if (punchRecordList.Count == 0)
{
appRemindList.AddRange(new AppRemindListDto()
{
Title = "未打卡",
Content = $"{item.SupervisedPersonName}的案件({item.CaseName})在时间点:[{DateTime.Now.ToString("yyyy/MM/dd")} {datehh}]未打卡",
CheckStatus = CheckStatusEnum.NotChecked,
CreatedUserId = item.SupervisedPersonId,
CreatedTime = DateTime.Now,
SupervisedPersonId = item.SupervisedPersonId,
SupervisedPersonName = item.SupervisedPersonName,
SupervisorId = item.SupervisorId,
SupervisorName = item.SupervisorName,
CaseId = item.CaseId
});
}
}
catch (Exception ex)
{
throw;
}
}
}
}
//如果有提醒
if (!appRemindList.Any()) return ResultOutput.Ok();
{
//添加到预警表
var earlyEntities = appRemindList.Select(w => new AppEarlyWarningAddInput(YitIdHelper.NextId())
{
Title = dict == null ? "" : dict.Name,
CaseId = w.CaseId.Value,
Content = w.Content,
EarlyWarningTypeId = dict?.Id ?? default,
SupervisedPersonId = w.SupervisedPersonId,
SupervisedPersonName = w.SupervisedPersonName,
}).ToList();
//如果添加了未打卡时间段的记录就不添加了
var earlyWarningIds = earlyEntities.Select(w => w.EarlyWarningTypeId).ToList();
var earlyWarningCaseIds = earlyEntities.Select(w => w.CaseId).ToList();
var earlyWarningSupervisedPersonIds = earlyEntities.Select(w => w.SupervisedPersonId).ToList();
//获取当前预警类型的数据
var alreadyEarlyWarning = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => earlyWarningIds.Contains(w.EarlyWarningTypeId) && earlyWarningCaseIds.Contains(w.CaseId) && earlyWarningSupervisedPersonIds.Contains(w.SupervisedPersonId))
.ToListAsync();
//去掉已经存在的
earlyEntities = earlyEntities.Where(earlyEntity =>
!alreadyEarlyWarning.Exists(w =>
w.EarlyWarningTypeId == earlyEntity.EarlyWarningTypeId &&
w.CaseId == earlyEntity.CaseId &&
w.SupervisedPersonId == earlyEntity.SupervisedPersonId &&
earlyEntity.Content!.Contains(w.Content))).ToList();
await _earlyWarningService.BatchAddAsync(earlyEntities);
#region 循环判断每一个未打卡预警,对app_case_supervised_person表的AttendanceRecord字段加一,若AttendanceRecord大于预警阈值,进行短信通知
foreach (var item in earlyEntities)
{
var person = await _appSupervisedPersonRepository.AsQueryable(false, true).Where(w => w.CaseId == item.CaseId && w.SupervisedPersonId == item.SupervisedPersonId).ToListAsync();
if (person.Count > 0)
{
person.FirstOrDefault().AttendanceRecord +=1;
await _appSupervisedPersonRepository.UpdateAsync(person);
var appCase = await _appCaseManagementRepository.AsQueryable(false, true).Where(w => w.Id == item.CaseId).ToListAsync();
if(appCase.FirstOrDefault().Threshold<= person.FirstOrDefault().AttendanceRecord)
{
var supervisedPerson = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == item.SupervisedPersonId).ToListAsync();
//通知被监管人
await _smsService.SendMessageSMS(MessageAlertTypeEnum.Alert, "", supervisedPerson.FirstOrDefault().Phone, DateTime.Now, "连续未打卡", "", item.SupervisedPersonName);
var supervisorList = await _appCaseSupervisorRepository.AsQueryable(false, true).Where(w => w.CaseId == item.CaseId).ToListAsync();
foreach (var sup in supervisorList)
{
var supervisor = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == sup.SupervisorId).ToListAsync();
//发短信给监管人,提醒被监管人脱离监管区域
await _smsService.SendMessageSMS(MessageAlertTypeEnum.RegulatoryAlert, supervisor.FirstOrDefault().UserName, supervisor.FirstOrDefault().Phone, DateTime.Now, "连续未打卡", "", item.SupervisedPersonName);
}
}
}
}
#endregion
//根据当前被监管人员的预警信息,计算出应该被通知的人员(被监管人员自己、监管人、管理员)
var earlyWarningRecord = await base.GetEarlyWarningRecord(earlyEntities);
//signalR通知
await _clientNotifyService.RealTimeWarningToPc(new RealTimeWarningToPcInput()
{
AppRemindListDtos = appRemindList,
SubscriberIds = earlyWarningRecord.Select(w => w.SubscriberId).ToList()
});
}
//返回
return ResultOutput.Ok();
}
#region Private
/// <summary>
///
/// </summary>
/// <param name="sourse"></param>
/// <param name="startStr"></param>
/// <param name="endStr"></param>
/// <returns></returns>
public static DateTime? MidStrEx(string sourse, string startStr, string endStr, DateTime? punchedTime)
{
var result = string.Empty;
var rtnDateTime = punchedTime;
try
{
var startIndex = sourse.IndexOf(startStr, StringComparison.Ordinal);
if (startIndex == -1) return punchedTime;
var tmpStr = sourse.Substring(startIndex + startStr.Length);
var endIndex = tmpStr.IndexOf(endStr, StringComparison.Ordinal);
if (endIndex == -1) return punchedTime;
result = tmpStr.Remove(endIndex);
rtnDateTime = DateTime.Parse(result);
}
catch (Exception)
{
}
return rtnDateTime;
}
#endregion Private
}
}