using ATS.NonCustodial.Application.Base; using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries; using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth; using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output; using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS; using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppAnnouncements; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppAnnouncements.Input; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications.Input; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications.Output; 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.AppCaseManagements.AppSignsInformations; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppSignsInformations.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.Apps; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Input; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Directories; using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Directories.Output; 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.Application.Impl.Admins; using ATS.NonCustodial.Application.Impl.Business.CaseManagements; using ATS.NonCustodial.Application.Impl.Business.IM; 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.Entities.Business.IM; using ATS.NonCustodial.Domain.Entities.Business.MaterialManager; 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.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.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using NPOI.SS.UserModel; using System.IO; namespace ATS.NonCustodial.Application.Impl.Business { /// /// App接口 /// /// Author:mxg /// CreatedTimed:2022-06-12 03:40 PM [DynamicApi(Area = "admin")] public class AppManagementService : AdminCommonService, IAppManagementService, IDynamicApi { #region Identity /// /// 案子管理人员 /// private readonly IEfRepository _appSupervisorRepository; private readonly IEfRepository _appSessionMessageRepository; private readonly IAuthService _authService; private readonly IAppCaseManagementService _appCaseManagementService; private readonly IAppSignsInformationService _appSignsInformationService; private readonly IAppPunchRecordService _appPunchRecordService; private readonly IAppBusinessApplicationService _appBusinessApplicationService; private readonly IEfRepository _appBusinessApplicationRepository; private readonly IEfRepository _appFileAccessRecordsRepository; private readonly IEfRepository _appAnnouncementRepository; private readonly IEfRepository _appEarlyWarningRepository; private readonly IEfRepository _appEarlyWarningViewStatisticsRepository; private readonly IEfRepository _appAnnouncementViewStatisticsRepository; private readonly IEfRepository _appBusinessApplicationViewStatisticsRepository; private readonly IEfRepository _appDirectoryDescriptorRepository; private readonly IEfRepository _appFileDescriptorRepository; private readonly IHubContext _hubContext; private readonly IEfRepository _appUserRepository; private readonly IAppEarlyWarningService _appEarlyWarningService; private readonly IAppAnnouncementService _appAnnouncementService; private readonly IAppDirectorDescriptorService _appDirectorDescriptorService; private readonly ISMSService _smsService; /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public AppManagementService(IEfRepository appSupervisorRepository, IEfRepository appSupervisedPersonRepository, IEfRepository appManagementRepository, IEfRepository appSupervisedPersonRealTimeLocationRepository, IUserService userService, IAppDictionaryService appDictionaryService, IAppDirectorDescriptorService appDirectorDescriptorService, IAppCaseManagementService appCaseManagementService, IAppSignsInformationService appSignsInformationService, IAppPunchRecordService appPunchRecordService, IAppBusinessApplicationService appBusinessApplicationService, IEfRepository appBusinessApplicationRepository, IEfRepository appFileAccessRecordsRepository, IEfRepository appAnnouncementRepository, IEfRepository appEarlyWarningRepository, IEfRepository appAnnouncementViewStatisticsRepository, IEfRepository appBusinessApplicationViewStatisticsRepository, IEfRepository appDirectoryDescriptorRepository, IEfRepository appFileDescriptorRepository, IAuthService authService, IEfRepository appUserRepository, IHubContext hubContext, IEfRepository appSessionMessageRepository, IAppEarlyWarningService appEarlyWarningService, IAppAnnouncementService appAnnouncementService, IEfRepository appEarlyWarningViewStatisticsRepository, ISMSService smsService) : base( appManagementRepository, appSupervisorRepository, appSupervisedPersonRepository, userService, appDictionaryService, appSupervisedPersonRealTimeLocationRepository) { _appSupervisorRepository = appSupervisorRepository; _appCaseManagementService = appCaseManagementService; _appFileAccessRecordsRepository = appFileAccessRecordsRepository; _appSignsInformationService = appSignsInformationService; _appPunchRecordService = appPunchRecordService; _appBusinessApplicationService = appBusinessApplicationService; _appBusinessApplicationRepository = appBusinessApplicationRepository; _appAnnouncementRepository = appAnnouncementRepository; _appEarlyWarningRepository = appEarlyWarningRepository; _appAnnouncementViewStatisticsRepository = appAnnouncementViewStatisticsRepository; _appBusinessApplicationViewStatisticsRepository = appBusinessApplicationViewStatisticsRepository; _authService = authService; _hubContext = hubContext; _appDirectorDescriptorService = appDirectorDescriptorService; _appSessionMessageRepository = appSessionMessageRepository; _appUserRepository = appUserRepository; _appEarlyWarningService = appEarlyWarningService; _appAnnouncementService = appAnnouncementService; _appEarlyWarningViewStatisticsRepository = appEarlyWarningViewStatisticsRepository; _appDirectoryDescriptorRepository = appDirectoryDescriptorRepository; _appFileDescriptorRepository = appFileDescriptorRepository; _smsService = smsService; } #endregion Identity #region 案件管理(监管人) /// /// 获取监管人员下的所有被监管人员人信息 /// /// 被监管人员名字 /// /// /// public async Task>> GetSupervisedPersonListByName(string? name) { //CaseProgressEnum案件已结束的不再展示 var rtn = (await GetCaseListDetail(name)).Where(w => w.Latitude != null && w.Longitude != null&&w.CaseProgress!= CaseProgressEnum.Closed).ToList(); //返回结果 return (IResultOutput>)ResultOutput.Ok(rtn); } /// /// 获取监管人员下的所有被监管人员人信息(通过案件分组) /// /// /// public async Task>> GetSupervisedPersonListByNameToCaseGroup(string? name) { var rtn = await GetCaseListDetailByIm(name); var dataGroup = rtn.GroupBy(w => new { w.CaseId, w.CaseName }) .Select(w => new SupervisedPersonListGroupOutput() { CaseId = w.Key.CaseId, CaseName = w.Key.CaseName, PersonList = w.ToList() }); return (IResultOutput>)ResultOutput.Ok(dataGroup); } /// /// 点击被监管人员查看其案子明细 /// /// /// /// /// ###### 入参示例 /// { /// "caseId": 300418976542789, /// "superPersonId": 297606179328069 /// } /// [HttpPost] public async Task> GetSuperPersonCaseDetail(GetSuperPersonCaseDetailInput input) { var caseDetail = await _appCaseManagementRepository.FindAsync(input.CaseId); if (caseDetail == null) return (IResultOutput)ResultOutput.NotOk("当前案子不存在!"); var caseDto = Mapper.Map(caseDetail); //裁决状态 caseDto.JudgmentStatusName = (await _appDictionaryService.GetDicByDicId(caseDto.JudgmentStatusId))?.Name; //案件类型 caseDto.CaseTypeName = (await _appDictionaryService.GetDicByDicId(caseDto.CaseTypeId))?.Name; //获取打卡时间区间分钟 var mis = await base.GetDictionariesOutput("plan_time", "interval"); caseDto.interval = mis.Value; var isAdmin = await _userService.IsAdmin(User.Id); //监管人员 var sp = await _appSupervisorRepository .AsQueryable(false, true) .Where(w => w.CaseId == caseDetail.Id && (isAdmin.IsAdmin || w.SupervisorId == User.Id)) .ToListAsync(); caseDto.SupervisorId = sp?.Select(w => w.SupervisorId)?.JoinAsString(","); caseDto.SupervisorName = sp?.Select(w => w.SupervisorName)?.JoinAsString(","); //被监管人员 var spR = await _appSupervisedPersonRepository .AsQueryable(false, true) .FirstOrDefaultAsync(w => w.CaseId == caseDetail.Id && w.SupervisedPersonId == input.SuperPersonId); caseDto.SupervisedPersonUserId = spR?.SupervisedPersonId; caseDto.SupervisedPersonId = spR?.Id; caseDto.EnterFace = spR?.EnterFace; caseDto.SupervisedPersonName = spR?.SupervisedPersonName; caseDto.ElectricFenceId = spR?.ElectricFenceId; caseDto.IdCard = spR?.IdCard; //案件类型() var caseType = (await _appDictionaryService.GetDicByDicId(caseDto.CaseTypeId)); if (caseType.Value.IsNotNullOrWhiteSpace() && caseType.Value!.IndexOf(",", StringComparison.Ordinal) > 0) { caseDto.AlertTypeLevelRules = caseType.Value; var caseTypeArray = caseType.Value.Split(","); if (caseTypeArray.Length >= 2) caseDto.CaseTypeName = $"预警 {caseTypeArray[0]} 次变黄,预警 {caseTypeArray[1]} 次变红"; } //返回结果 return (IResultOutput)ResultOutput.Ok(caseDto); } /// /// 获取案件批注内容列表 /// /// /// /// /// ###### 入参示例 /// 299059431809093 /// public async Task>> GetAppCaseNotes(long id) => (IResultOutput>)await _appCaseManagementService.GetCaseNotes(id); /// /// 根据被监管人员Id查询体征信息 /// /// /// /// /// ###### 入参示例 /// 297606179328069 /// public async Task> GetAppSignsInformation(long supervisedPersonId) => (IResultOutput)await _appSignsInformationService.Get(supervisedPersonId); /// /// 获取被监管人员的打卡记录(被监管人和监管人App通用) /// /// /// /// /// ###### 入参示例 /// { /// "pageIndex": 1, /// "pageSize": 10, /// "caseId": 300418976542789, /// "supervisedPersonId": 297606179328069 /// } /// [HttpPost] public async Task>> GetAppPunchRecord(GetAppPunchRecordInput input) { var userCase = await base.GetCurrentSupervisePersonProcessingCase(input.SupervisedPersonId ?? User.Id); if (userCase == null) return new ResultOutput>(); return (IResultOutput>)await _appPunchRecordService.GetPageAsync(new AppPunchRecordGetPageInput() { Id = userCase.CaseId, SupervisedPersonId = input.SupervisedPersonId ?? User.Id, PageIndex = input.PageIndex, PageSize = input.PageSize }); } /// /// 获取被监管人员历史轨迹 /// /// /// /// /// ###### 入参示例 /// { /// "pageIndex": 1, /// "pageSize": 10, /// "caseId": 300418976542789, /// "supervisedPersonId": 297606179328069 /// } /// [HttpPost] public async Task>> GetAppHistoricalTrack(GetAppPunchRecordInput input) { var rtn = await _appSupervisedPersonRealTimeLocationRepository .Where(w => w.SupervisedPersonId == input.SupervisedPersonId && w.CaseId == input.CaseId) .WhereIf(input.TimeSearch is { SearchType: SearchTimeTypeEnums.CreatedTimed, BeginTime: { } }, p => p.CreatedTime >= input.TimeSearch!.BeginTime) .WhereIf(input.TimeSearch is { SearchType: SearchTimeTypeEnums.CreatedTimed, EndTime: { } }, p => p.CreatedTime < input.TimeSearch!.EndTime) .OrderBy(w => w.CreatedTime) .ProjectTo(Mapper.ConfigurationProvider) .ToListAsync(); return (IResultOutput>)ResultOutput.Ok(rtn); } /// /// 获取监管人员手里的案子列表[分页] /// /// /// /// ###### 入参示例 /// { /// "supervisorId": 298680001155141, /// "caseProgress": 0 /// } /// [HttpPost] public async Task>> GetAppSupervisorCaseList(GetSupervisorCaseListInput input) { var rtn = await _appCaseManagementService.GetSupervisorCaseList(input); return (IResultOutput>)rtn; } /// /// 获取案子明细 /// /// /// /// /// ###### 入参示例 /// 300418976542789 /// public async Task> GetAppCaseDetail(long caseId) { var caseDetail = await _appCaseManagementRepository.FindAsync(caseId); if (caseDetail == null) return (IResultOutput)ResultOutput.NotOk("当前案子不存在!"); var caseDto = Mapper.Map(caseDetail); //裁决状态 caseDto.JudgmentStatusName = (await _appDictionaryService.GetDicByDicId(caseDto.JudgmentStatusId))?.Name; //案件类型() var caseType = (await _appDictionaryService.GetDicByDicId(caseDto.CaseTypeId)); if (caseType.Value.IsNotNullOrWhiteSpace() && caseType.Value!.IndexOf(",", StringComparison.Ordinal) > 0) { caseDto.AlertTypeLevelRules = caseType.Value; var caseTypeArray = caseType.Value.Split(","); if (caseTypeArray.Length >= 2) caseDto.CaseTypeName = $"预警 {caseTypeArray[0]} 次变黄,预警 {caseTypeArray[1]} 次变红"; } //监管人员 caseDto.SupervisorName = (await _appSupervisorRepository .AsQueryable(false, true) .Where(w => w.CaseId == caseDetail.Id) .ToListAsync()) .Select(w => w.SupervisorName)! .JoinAsString(","); //被监管人员 caseDto.SupervisedPersonName = (await _appSupervisedPersonRepository .AsQueryable(false, true) .Where(w => w.CaseId == caseDetail.Id) .ToListAsync()) .Select(w => w.SupervisedPersonName)! .JoinAsString(","); return (IResultOutput)ResultOutput.Ok(caseDto); } /// /// 添加案件重要节点批注 /// /// /// [HttpPost] public async Task AddAppCaseNotes(AddCaseNotesInput input) => await _appCaseManagementService.AddCaseNotes(input); #endregion 案件管理(监管人) #region 业务审核(监管人) /// /// 获取当前监管人拥有的被监管人的业务申请记录列表[分页] /// /// /// /// /// 业务申请审核状态(0:待审核 1:已通过 2:已驳回) [HttpPost] public async Task>> GetAppBusinessByStatusListAsync(GetAppBusinessByStatusListPageInput input) { var data = await _appCaseManagementService.GetCaseSuperviseList(); var caseIds = data.Select(w => w.CaseId).ToList(); //业务申请列表 var businessList = await _appBusinessApplicationRepository .AsQueryable(false, true) .Where(w => w.AuditStatus == input.AuditStatus && caseIds.Contains(w.CaseId)) .OrderByDescending(w => w.CreatedTime) .ProjectTo(Mapper.ConfigurationProvider) .PagedAsync(input) .ConfigureAwait(true); return (IResultOutput>)ResultOutput.Ok(businessList); } /// /// 获取业务申请明细 /// /// /// public async Task> GetAppBusinessDetail(long id) => (IResultOutput)await _appBusinessApplicationService.GetAsync(id); /// /// 批量审核(App业务审核) /// /// /// [HttpPost] public async Task AppBusinessBatchAudit(BatchAuditInput input) => await _appBusinessApplicationService.BatchAudit(input); /// /// 监管人提醒 /// /// public async Task>> AppSupervisorReminds() { var data = await _appCaseManagementService.GetCaseSuperviseList(); var caseIds = data.Select(w => w.CaseId).ToList(); //业务申请列表 var businessList = await _appBusinessApplicationRepository .AsQueryable(false, true) .Where(w => caseIds.Contains(w.CaseId)) .OrderByDescending(w => w.CreatedTime) .ProjectTo(Mapper.ConfigurationProvider) .ToListAsync(); return (IResultOutput>)ResultOutput.Ok(businessList); } /// /// 监管人简化版提醒(监管人) /// /// [HttpPost] public async Task>> GetSimplifySupervisorReminds(GetSimplifySupervisorRemindsPageInput input) { var rtn = new List(); //业务申请提醒 var data = await _appCaseManagementService.GetCaseSuperviseList(); var caseIds = data.Select(w => w.CaseId).ToList(); var rtnBusiness = (from bp in _appBusinessApplicationRepository.AsQueryable(false, true) join bavs in _appBusinessApplicationViewStatisticsRepository.AsQueryable(false, true) on bp.Id equals bavs.AppBusinessApplicationId where caseIds.Contains(bavs.CaseId) select new SupervisorRemindOutput() { Id = bp.Id, Title = bp.ApplicationTypeName, Content = bp.ApplicationDescription, CreatedUserId = bp.CreatedUserId, CreatedUserName = bp.CreatedUserName, CreatedTime = bp.CreatedTime, CheckStatus = bavs.CheckStatus, CheckTime = bavs.CheckTime }); if (rtnBusiness.Any()) rtn.AddRange(rtnBusiness); var totalCount = rtnBusiness.Count(); var pageDataList = await rtnBusiness .OrderByDescending(w => w.CheckTime) .Skip((input.PageIndex - 1) * input.PageSize) .Take(input.PageSize) .ToListAsync(); //返回结果 return (IResultOutput>)ResultOutput.Ok(new PagedList() { TotalCount = totalCount, Data = pageDataList.Distinct((x, y) => x.Id == y.Id).ToList() }); } /// /// 批量设置消息提示是否查阅(监管人) /// /// /// [HttpPost] public async Task GetCheckSupervisorRemindsStatus(GetCheckSupervisorRemindsStatusInput input) { if (!input.BusinessApplicationIds.Any()) return ResultOutput.NotOk("参数不能为空"); var busViewList = await _appBusinessApplicationViewStatisticsRepository .Where(w => input.BusinessApplicationIds.Contains(w.AppBusinessApplicationId) && w.SubscriberId == User.Id) .ToListAsync(); foreach (var item in busViewList) { item.CheckStatus = input.CheckStatus; if (input.CheckStatus == CheckStatusEnum.Checked) { item.CheckTime = DateTime.Now; } else { item.CheckTime = null; } } await _appBusinessApplicationViewStatisticsRepository.UpdateAsync(busViewList); return ResultOutput.Ok(); } #endregion 业务审核(监管人) #region 聊天(IM)(监管人-被监管人) /// /// 获取当前监管人下所有的被监管人(聊天列表) /// /// public async Task>> GetChatSupervisedPersonAsync() { var dataList = await (from sp in _appSupervisorRepository.AsQueryable(false, true).Where(w => w.SupervisorId == User.Id) join csp in _appSupervisedPersonRepository.AsQueryable(false, true) on sp.CaseId equals csp.CaseId select new ChatSupervisedPersonListDto() { CaseId = sp.CaseId, SupervisorId = sp.SupervisorId, SupervisorName = sp.SupervisorName, SupervisedPersonId = csp.SupervisedPersonId, SupervisedPersonName = csp.SupervisedPersonName, SupervisorAvatar = _user.Name }).ToListAsync(); return (IResultOutput>)ResultOutput.Ok(dataList); } /// /// 获取当前监管人下所有的被监管人(聊天列表)[监管人+被监管人] /// /// [HttpPost] public async Task>> GetChatSimplifySupervisedPersonListAsync(GetChatSimplifySupervisedPersonPageInput input) { var dataPerson = await GetChatPersonList(new GetChatPersonListPageInput() { PageIndex = input.PageIndex, PageSize = input.PageSize }); var receiverList = await _userService.GetAllByConditionAsync(new BatchIdsInput() { Ids = dataPerson.Data.Where(q => q.ReceiverId != null) .Select(w => w.ReceiverId!.Value) .Union(dataPerson.Data.Select(w => w.SenderId!.Value)) .Distinct() .ToList() }); //用来存储职位及对应index var postDict = new Dictionary(); //处理头像 dataPerson.Data = dataPerson.Data.Where(q => q.ReceiverId != null).Select((item, index) => { item.SenderAvatar ??= receiverList.FirstOrDefault(w => w.Id == item.SenderId)?.Avatar ?? "/avatar/default.png"; item.ReceiverAvatar ??= receiverList.FirstOrDefault(w => w.Id == item.ReceiverId)?.Avatar ?? "/avatar/default.png"; var EnterFace = base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q => q.SupervisedPersonId == item.ReceiverId).FirstOrDefault()?.EnterFace; if (!string.IsNullOrEmpty(EnterFace)) item.Avatar ??= EnterFace; else item.Avatar ??= receiverList.FirstOrDefault(w => w.Id == item.ReceiverId)?.Avatar ?? "/avatar/default.png"; //职位名字 if (User.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson) return item; { var positionName = receiverList.FirstOrDefault(w => w.Id == item.ReceiverId)?.PositionName; if (postDict.ContainsKey(positionName)) { postDict[positionName] += 1; } else { postDict.Add(positionName, 1); } item.ReceiverName = positionName + postDict[positionName].ToString(); } return item; }).ToList(); //分页处理消息 List pageData = new EditableList(); foreach (var chatDto in dataPerson.Data.Where(q => q.ReceiverId != null)) { /*当前聊天页面,逻辑应该是发送者是xxx,接收者是当前登录人 * chatDto也就是列表人员的Id==当前登录人的Id(也就是说当前User为接收者) */ //当前聊天的所有消息 var sessionMessage = _appSessionMessageRepository .AsQueryable(false, true) .Where(w => w.CaseId == chatDto.CaseId && ( w.SenderId == chatDto.SenderId && w.ReceiverId == chatDto.ReceiverId || w.SenderId == chatDto.ReceiverId && w.ReceiverId == chatDto.SenderId) ); var messageList = await sessionMessage.OrderByDescending(w => w.CreatedTime).ToListAsync(); var dto = Mapper.Map(chatDto); dto.UnReadCount = messageList.Count(w => w.CheckStatus == CheckStatusEnum.NotChecked && w.SenderId == chatDto.ReceiverId && w.ReceiverId == chatDto.SenderId); dto.LastMessage = messageList.FirstOrDefault()?.Content; dto.LastMsgTime = messageList.FirstOrDefault()?.CreatedTime; pageData.Add(dto); } //返回结果 return (IResultOutput>)ResultOutput.Ok(new PagedList() { TotalCount = dataPerson.TotalCount, Data = pageData }); } #endregion 聊天(IM)(监管人-被监管人) #region (被监管人) /// /// 被监管人首页数据 /// /// 被监管人手机唯一标识 /// public async Task> GetSupervisedPersonHomepage(string imei) { var data = await (from c in _appCaseManagementRepository.AsQueryable(false, true) join spcr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals spcr.CaseId where spcr.IMEI == imei && c.CaseProgress != CaseProgressEnum.Closed select new { c.Id, spcr.SupervisedPersonId }).FirstOrDefaultAsync(); if (data == null) return new ResultOutput(); return await this.GetSuperPersonCaseDetail(new GetSuperPersonCaseDetailInput() { CaseId = data!.Id, SuperPersonId = data.SupervisedPersonId }); } /// /// 被监管人员提醒列表 /// /// /// [HttpPost] public async Task>> GetAppRemindListAsync(AppRemindInput input) { List rtn; var totalCount = 0; //如果SupervisedPersonId不为空并查询结果为空执行下面查询 var currentCase = await GetCurrentSupervisePersonProcessingCase(input.SupervisedPersonId!=null ? (long)input.SupervisedPersonId : User.Id); if (input.RemindType == AppRemindTypeEnum.EarlyWarning) { var earlyWarningList = (from ew in _appEarlyWarningRepository.AsQueryable(false, true) join ewv in _appEarlyWarningViewStatisticsRepository.AsQueryable(false, true) on ew.Id equals ewv.AppEarlyWarningId where ewv.SubscriberId == currentCase.SupervisedPersonId && ewv.CaseId == currentCase.CaseId select new AppRemindListDto() { Id = ew.Id, Title = ew.Title, CreatedTime = ew.CreatedTime, CreatedUserId = ew.CreatedUserId, CreatedUserName = ew.CreatedUserName, Content = ew.Content, CheckStatus = ewv.CheckStatus, CheckTime = ewv.CheckTime, CaseId = ew.CaseId, CaseName = ew.CaseName }); totalCount = earlyWarningList.Count(); var WarningList = new List(); var NotChecked = earlyWarningList.Where(q => q.CheckStatus == CheckStatusEnum.NotChecked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(NotChecked); var Checked = earlyWarningList.Where(q => q.CheckStatus == CheckStatusEnum.Checked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(Checked); rtn = WarningList .Skip((input.PageIndex - 1) * input.PageSize) .Take(input.PageSize) .ToList(); } else { var noteList = await _appAnnouncementViewStatisticsRepository .AsQueryable(false, true) .Where(w => w.SupervisedPersonId == currentCase.SupervisedPersonId && w.CaseId == currentCase.CaseId) .ToListAsync(); totalCount = noteList.Count; var WarningList = new List(); var NotChecked = noteList.Where(q => q.CheckStatus == CheckStatusEnum.NotChecked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(NotChecked); var Checked = noteList.Where(q => q.CheckStatus == CheckStatusEnum.Checked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(Checked); noteList = noteList .Skip((input.PageIndex - 1) * input.PageSize) .Take(input.PageSize) .ToList(); rtn = noteList.Select(w => new AppRemindListDto() { Id = w.AnnouncementId, Title = w.Title, CreatedTime = w.CreatedTime, CreatedUserId = w.CreatedUserId, CreatedUserName = w.CreatedUserName, CheckStatus = w.CheckStatus, CheckTime = w.CheckTime ?? null, CaseId = w.CaseId, CaseName = w.CaseName }).ToList(); } return (IResultOutput>)ResultOutput.Ok(new PagedList() { TotalCount = totalCount, Data = rtn.ToList() }); } /// /// 被监管人提醒明细 /// /// /// [HttpPost] public async Task> GetAppRemindDetail(GetAppRemindDetailInput input) { GetAppRemindDetailDto? rtn = null; if (input.RemindType == AppRemindTypeEnum.EarlyWarning) { //先修改状态 await _appEarlyWarningService.BatchSetCheckStatus(new SetCheckStatusInput() { Ids = new EditableList() { input.Id }, CheckStatus = CheckStatusEnum.Checked }); rtn = await base.GetAsync(_appEarlyWarningRepository, input.Id); } else { //先修改状态 await _appAnnouncementService.BatchSetCheckStatus(new BatchSetCheckStatusInput() { AnnouncementIds = new EditableList() { input.Id }, CheckStatus = CheckStatusEnum.Checked }); rtn = await base.GetAsync(_appAnnouncementRepository, input.Id); } return (IResultOutput)ResultOutput.Ok(rtn); } /// /// 被监管人员添加业务申请 /// /// [HttpPost] public async Task AddAppBusinessAsync(AppBusinessApplicationCreateOrModifyInput input) { //根据案件找监管人,找到多个,均发送消息提醒 var currentUserCase = await base.GetCurrentSupervisePersonProcessingCase(User.Id); var supervisorList = await _appSupervisorRepository .AsQueryable(false, true) .Where(w => w.CaseId == currentUserCase.CaseId) .ToListAsync(); var applicationType = await base.GetDictionariesOutput("application_type", "df"); foreach (var supervisor in supervisorList) { var user = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == supervisor.SupervisorId).ToListAsync(); //发短信给监管人,提醒处理审批 await _smsService.SendMessageSMS(MessageAlertTypeEnum.ReviewNotification, user.FirstOrDefault().UserName, user.FirstOrDefault().Phone, DateTime.Now, applicationType.Name, "", currentUserCase.SupervisedPersonName); } return await _appBusinessApplicationService.CreateOrModify(input); } /// /// 获取被监管人员业务申请列表(正在进行的案件) /// /// /// [HttpPost] public async Task>> GetAppBusinessListAsync(GetAppBusinessListPageInput input) { var query = (from c in _appCaseManagementRepository.AsQueryable(false, true).Where(w => w.CaseProgress != CaseProgressEnum.Closed) join ba in _appBusinessApplicationRepository.AsQueryable(false, true) on c.Id equals ba.CaseId select ba) .WhereIf(input.AuditStatus != null, w => w.AuditStatus == input.AuditStatus) .Where(w => w.SupervisedPersonId == (input.SupervisedPersonId!=null ? input.SupervisedPersonId : User.Id)) .OrderByDescending(w => w.CreatedTime); //正在进行的案件 var totalCount = await query.CountAsync(); var rtn = await query.Skip((input.PageIndex - 1) * input.PageSize) .Take(input.PageSize) .ProjectTo(Mapper.ConfigurationProvider) .ToListAsync(); return (IResultOutput>)ResultOutput.Ok(new PagedList() { TotalCount = totalCount, Data = rtn }); } /// /// 获取被监管人员学习资料(正在进行的案件) /// /// /// [HttpPost] public async Task GetAppfileaccessrecordsAsync(GetAppBusinessListPageInput input) { var list = new List(); var query = (from c in _appCaseManagementRepository.AsQueryable(false, true).Where(w => w.CaseProgress != CaseProgressEnum.Closed) join a in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals a.CaseId join ba in _appFileAccessRecordsRepository.AsQueryable(false, true) on a.SupervisedPersonId equals ba.SupervisedPersonId select ba) .Where(w => w.SupervisedPersonId == (input.SupervisedPersonId!=null ? input.SupervisedPersonId : User.Id)) .OrderByDescending(w => w.CreatedTime); var Direclist = (from c in _appDirectoryDescriptorRepository.AsQueryable(false, true) join a in _appFileDescriptorRepository.AsQueryable(false, true) on c.Id equals a.DirectoryId select new{ typename=c.Name, a.Name,a.Id,a.DirectoryId }).ToList(); foreach (var item in Direclist) { var Direcbol = query.ToList().Where(q => q.FileDescriptorId == item.Id&&q.CaseId==(input.CaseId!=null? input.CaseId:0)).OrderByDescending(q=>q.CreatedTime).ToList(); if (Direcbol.Count > 0) { list.Add(new { typename = $"{item.typename}", name = $"{item.Name}", time = $"{Direcbol.First()?.CreatedTime}", bol = true }); } else { list.Add(new { typename = $"{item.typename}", name = $"{item.Name}", time="", bol = false }); } } var totalCount = list.Count(); var pagelist = list.Skip((input.PageIndex - 1) * input.PageSize) .Take(input.PageSize); return ResultOutput.Ok(new { TotalCount = totalCount, Data = pagelist }); } /// /// App根据业务Id获取业务明细 /// /// /// public async Task> GetAppBusinessDetailById(long id) => (IResultOutput)await _appBusinessApplicationService.GetAsync(id); /// /// 添加打卡记录 /// /// /// public async Task AddPunchRecord(AppPunchRecordAddInput input) => await _appPunchRecordService.AddAsync(input); /// /// 被监管人登录 /// /// IMEI是被监管人在APP上提交申请时,会自动上报的手机唯一标识数据。(获取自动登录) /// [HttpGet] [AllowAnonymous] public async Task> SupervisedPersonLogin(string imei) { var spData = await _appSupervisedPersonRepository.FindAsync(w => w.IMEI == imei); if (spData is { IsBound: true, ApprovalStatus: ApprovalStatusEnum.PassReview }) { var userData = await _appUserRepository.FindAsync(w => spData.SupervisedPersonId == 0 ? w.IdCard == spData.IdCard : w.Id == spData.SupervisedPersonId); var token = await _authService.GetToken(new AuthLoginOutput() { Id = spData.SupervisedPersonId, UserName = spData.SupervisedPersonName, NickName = userData?.NickName, Avatar = userData?.Avatar, Phone = spData.Phone, ChatPersonType = userData!.ChatPersonType, PositionName = userData.PositionName, IdCard = userData.IdCard }); return (IResultOutput)ResultOutput.Ok(token); } else { return (IResultOutput)ResultOutput.NotOk(spData == null ? $"当前用户未注册!" : $"当前用户还在:{spData.ApprovalStatus.ToDescription()}"); } } /// /// 被监管人提交绑定申请(必须是在后台管理端的案件管理中添加了被监管人才能) /// /// /// 这个接口的作用其实就是用户和手机之间的绑定 [AllowAnonymous] public async Task SubmitBindingApplication(SubmitBindingApplicationInput input) { if (!string.IsNullOrEmpty(input.phone)) { bool checkCode = await _smsService.CheckCodeAsync(input.phone, input.checkCode, "CheckCode"); if (!checkCode) return ResultOutput.NotOk("无效验证码"); } //[1]校验当前账户是否是第一次绑定 //if (!await _appSupervisedPersonRepository.AnyAsync(w => w.IdCard == input.IdCard && !w.IsBound)) return ResultOutput.NotOk("当前身份没有被监管,请检查身份证是否输入正确"); if (!await _appSupervisedPersonRepository.AnyAsync(w => w.IdCard == input.IdCard)) return ResultOutput.NotOk("当前身份没有被监管,请检查身份证是否输入正确"); //[2]判断当前被监管人的案件是否为未关闭,关闭了就不能绑定了 var cspData = await (from c in _appCaseManagementRepository.AsQueryable(false, true) join spr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals spr.CaseId where c.CaseProgress != CaseProgressEnum.Closed && spr.IdCard == input.IdCard select new { c.CaseProgress, spr.SupervisedPersonId, spr.ApprovalStatus, spr.IMEI, spr.IdCard }) .ToListAsync(); //if (cspData.FirstOrDefault()?.IdCard != input.IdCard || cspData.FirstOrDefault()?.IMEI != input.IMEI) return ResultOutput.NotOk("当前身份和Iemi不匹配"); if (!cspData.Any(w => w.CaseProgress is CaseProgressEnum.InExecution or CaseProgressEnum.Pending or CaseProgressEnum.Examination or CaseProgressEnum.Hear)) return ResultOutput.NotOk("当前被监管人不存在进行中的案件"); //[3]修改审核状态 // var spData = await _appSupervisedPersonRepository.FindAsync(w => w.IdCard == input.IdCard && !w.IsBound); var spData = await _appSupervisedPersonRepository.FindAsync(w => w.IdCard == input.IdCard); if (spData == null) return ResultOutput.Ok(); spData.ApprovalStatus = ApprovalStatusEnum.PendingReview; spData.EnterFace = input.EnterFace; spData.IMEI = input.IMEI; var userdata = _appUserRepository.AsQueryable(false, true).Where(q => q.Id == spData.SupervisedPersonId).FirstOrDefault(); if (userdata!=null) { userdata.CId = input.CId; await _appUserRepository.UpdateAsync(userdata,UpdatingProps(q=>q.CId)); } await _appSupervisedPersonRepository.UpdateAsync(spData); return ResultOutput.Ok(); } /// /// 判断被监管人是否绑定了 /// /// IMEI是被监管人在APP上提交申请时,会自动上报的手机唯一标识数据。(获取自动登录) /// [AllowAnonymous] [HttpGet] public async Task> CheckSupervisedPersonIsBind(string imei) { var cspData = await (from c in _appCaseManagementRepository.AsQueryable(false, true) join spr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals spr.CaseId where c.CaseProgress != CaseProgressEnum.Closed && spr.IMEI == imei select new CheckSupervisedPersonIsBindOutput() { Name = c.Name, CaseProgress = c.CaseProgress, SupervisedPersonId = spr.SupervisedPersonId, SupervisedPersonName = spr.SupervisedPersonName, IsBound = spr.IsBound, ApprovalStatus = spr.ApprovalStatus }).FirstOrDefaultAsync(); if (cspData is { IsBound: true, ApprovalStatus: ApprovalStatusEnum.PassReview }) cspData.Token = (await SupervisedPersonLogin(imei)).Data; return (IResultOutput)ResultOutput.Ok(cspData); } /// /// 统计被监管人的打卡、学习、申请、聊天、提醒 /// /// public async Task>> SupervisedStatistics() { List rtn = new EditableList(); var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync(); var currentCase = await GetCurrentSupervisePersonProcessingCase(User.Id); //预警 rtn.Add(new SupervisedStatisticsOutput() { Key = "early_warning_type", Count = await _appEarlyWarningViewStatisticsRepository.AsQueryable(false, true) .Where(w => w.CaseId == currentCase.CaseId) .CountAsync(w => w.SubscriberId == User.Id && w.CheckStatus == CheckStatusEnum.NotChecked) + await _appAnnouncementViewStatisticsRepository.AsQueryable(false, true) .Where(w => w.CaseId != null && caseIds.Contains(w.CaseId.Value)) .CountAsync(w => w.SupervisedPersonId == User.Id && w.CheckStatus == CheckStatusEnum.NotChecked) }); //聊天 rtn.Add(new SupervisedStatisticsOutput() { Key = "chat", Count = await _appSessionMessageRepository .AsQueryable(false, true) // .Where(w => w.CaseId != null && caseIds.Contains(w.CaseId.Value)) .Where(w => w.CaseId == currentCase.CaseId) .CountAsync(w => w.ReceiverId == User.Id && w.CheckStatus == CheckStatusEnum.NotChecked) }); return (IResultOutput>)ResultOutput.Ok(rtn); } #endregion (被监管人) #region 文件上传(录入人脸、打卡视频) /// /// 文件上传(录入人脸、打卡视频) /// /// 上传文件类型:0 /// /// [HttpPost] [AllowAnonymous] public async Task SupervisedPersonUpload([FromQuery] UploadFileTypeEnum uploadFileType, [FromForm] IFormFile file) { var uploadConfig = LazyGetRequiredService(); var ufConfig = (uploadFileType == UploadFileTypeEnum.Image ? uploadConfig.Image : uploadConfig.Video); return await base.CustomizedUpload(file, User.Id, ufConfig, null); } #endregion 文件上传(录入人脸、打卡视频) #region Pc端提醒 /// /// 获取当前人的预警信息 /// /// public async Task> GetRemindListByCurrentUser() { //预警信息 var earlyList = await GetRemindListByCurrentUserPageAsync(new AppRemindPageInput() { PageIndex = 1, PageSize = 999999, CheckStatus = CheckStatusEnum.NotChecked }); //返回数据 return (IResultOutput)ResultOutput.Ok(new AppRemindListWithCountDto() { TotalCount = earlyList.Data.TotalCount, RemindList = earlyList.Data.Data.OrderByDescending(w => w.CreatedTime).ToList(), }); } /// /// 获取当前人的预警信息(分页查询) /// /// /// public async Task>> GetRemindListByCurrentUserPageAsync(AppRemindPageInput input) { 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 earlyList = await (from e in _appEarlyWarningRepository.AsQueryable(false, true) join ev in _appEarlyWarningViewStatisticsRepository.AsQueryable(false, true) on e.Id equals ev.AppEarlyWarningId where ev.SubscriberId == User.Id && caseIdList.Contains(e.CaseId) select new AppRemindListDto() { Id = e.Id, Title = e.Title, Content = e.Content, CheckStatus = ev.CheckStatus, CheckTime = ev.CheckTime, CreatedUserId = e.SupervisedPersonId, CreatedTime = e.CreatedTime, SupervisedPersonId = e.SupervisedPersonId, SupervisedPersonName = e.SupervisedPersonName, CaseId = e.CaseId }) .WhereIf(input.CheckStatus.HasValue, w => w.CheckStatus == input.CheckStatus) .ToListAsync(); earlyList = earlyList.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId && x.CreatedTime == y.CreatedTime).OrderByDescending(q => q.CreatedTime).ToList(); if (!input.CheckStatus.HasValue) { var WarningList = new List(); var NotChecked = earlyList.Where(q => q.CheckStatus == CheckStatusEnum.NotChecked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(NotChecked); var Checked = earlyList.Where(q => q.CheckStatus == CheckStatusEnum.Checked).OrderByDescending(q => q.CreatedTime).ToList(); WarningList.AddRange(Checked); earlyList = WarningList; } return (IResultOutput>)ResultOutput.Ok(new PagedList() { TotalCount = earlyList.Count, Data = earlyList.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList() }); } #endregion Pc端提醒 #region Private /// /// App获取案件管理公共逻辑方法(正在进行中的案件) /// /// /// private async Task> GetCaseListDetail(string? name) { //获取当前用户权限下的案件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 data = (await base.GetCurrentUserCaseListAsync()) .Where(W => W.AppCaseManagement!=null&& W.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed && caseIdList.Contains(W.AppCaseManagement.Id)) .Where(W => W.AppCaseSupervisedPerson != null&& caseIdList.Contains(W.AppCaseSupervisedPerson.CaseId)) .Where(W=>W.AppCaseSupervisor!=null && caseIdList.Contains(W.AppCaseSupervisor.CaseId)) .WhereIf(name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName!.Contains(name)) .Select(w => new { w.AppCaseManagement, w.AppCaseSupervisor, w.AppCaseSupervisedPerson }).ToList(); //当前登录人员下的所有被监管人员Ids var caseIds = data.Select(w => w.AppCaseManagement.Id).ToList(); var spIds = data.Where(q => q.AppCaseSupervisedPerson != null).Select(w => w.AppCaseSupervisedPerson.SupervisedPersonId).ToList(); //最新地理位置(注意根据被监管人设置的隐私等级时间获取xxx前最近一次的位置信息) var points = await base.GetSpLocationByPrivacyLevel(spIds, caseIds); //头像列表 var userAvatarList = await _userService.UserAvatarList(new BatchIdsInput() { Ids = spIds }); //处理地址坐标 var rtn = (from d in data.Where(q => q.AppCaseSupervisedPerson != null) join p in points on new { d.AppCaseSupervisedPerson.SupervisedPersonId, d.AppCaseSupervisedPerson.CaseId } equals new { p.SupervisedPersonId, p.CaseId } into pTemp from pt in pTemp.DefaultIfEmpty() select new { d, pt }).ToList() .Select(@t => new SupervisedPersonListOutput() { CaseId = @t.d.AppCaseSupervisedPerson.CaseId, CaseName = @t.d.AppCaseManagement.Name, UserId = User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson ? @t.d.AppCaseSupervisor.SupervisorId : @t.d.AppCaseSupervisedPerson!.SupervisedPersonId, UserName = User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson ? @t.d.AppCaseSupervisor.SupervisorName : @t.d.AppCaseSupervisedPerson.SupervisedPersonName, Latitude = @t.pt?.Latitude, Longitude = @t.pt?.Longitude, Address = @t.pt?.Place, Gender = @t.d.AppCaseSupervisedPerson.Gender, Avatar = userAvatarList.FirstOrDefault(w => w.UserId == @t.d.AppCaseSupervisedPerson!.SupervisedPersonId)?.Avatar, CaseTypeId = @t.d.AppCaseManagement.CaseTypeId, PrivacyLevel = @t.d.AppCaseSupervisedPerson.PrivacyLevel }).ToList(); rtn = rtn.Distinct((x, y) => x.CaseId == y.CaseId && x.UserId == y.UserId && x.Latitude == y.Latitude && x.Longitude == y.Longitude) .ToList(); //预警总次数 var earlyWarning = _appEarlyWarningRepository.AsQueryable(false, true); var dictList = await _appDictionaryService.GetDicByDicIds(new BatchIdsInput() { Ids = rtn.Select(w => w.CaseTypeId).ToList() }); foreach (var item in rtn) { item.TotalEarlyWarningCount = item.AlertType = earlyWarning.Where(w => w.SupervisedPersonId == item.UserId).Where(w => w.CaseId == item.CaseId).Count(); item.AlertTypeLevelRules = dictList.FirstOrDefault(w => w.Id == item.CaseTypeId)?.Value; } //返回结果 return rtn; } /// /// App获取案件管理公共逻辑方法(聊条管理) /// /// /// private async Task> GetCaseListDetailByIm(string? name) { //获取当前用户权限下的案件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 data = (await base.GetCurrentUserCaseListAsync()) .Where(W => W.AppCaseManagement!=null&& W.AppCaseSupervisedPerson != null && W.AppCaseSupervisor != null && W.AppCaseManagement.CaseProgress != CaseProgressEnum.Pending && caseIdList.Contains(W.AppCaseManagement.Id)&&caseIdList.Contains(W.AppCaseSupervisedPerson.CaseId)&&caseIdList.Contains(W.AppCaseSupervisor.CaseId)) .WhereIf(name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName!.Contains(name)) .Select(w => new { w.AppCaseManagement, w.AppCaseSupervisor, w.AppCaseSupervisedPerson }).ToList(); //当前登录人员下的所有被监管人员Ids var caseIds = data.Select(w => w.AppCaseManagement.Id).ToList(); var spIds = data.Where(q => q.AppCaseSupervisedPerson != null).Select(w => w.AppCaseSupervisedPerson.SupervisedPersonId).ToList(); //最新地理位置(注意根据被监管人设置的隐私等级时间获取xxx前最近一次的位置信息) var points = await base.GetSpLocationByPrivacyLevel(spIds, caseIds); //头像列表 var userAvatarList = await _userService.UserAvatarList(new BatchIdsInput() { Ids = spIds }); //处理地址坐标 var rtn = (from d in data.Where(q => q.AppCaseSupervisedPerson != null) join p in points on new { d.AppCaseSupervisedPerson.SupervisedPersonId, d.AppCaseSupervisedPerson.CaseId } equals new { p.SupervisedPersonId, p.CaseId } into pTemp from pt in pTemp.DefaultIfEmpty() select new { d, pt }).ToList() .Select(@t => new SupervisedPersonListOutput() { CaseId = @t.d.AppCaseSupervisedPerson.CaseId, CaseName = @t.d.AppCaseManagement.Name, UserId = User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson ? @t.d.AppCaseSupervisor.SupervisorId : @t.d.AppCaseSupervisedPerson!.SupervisedPersonId, UserName = User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson ? @t.d.AppCaseSupervisor.SupervisorName : @t.d.AppCaseSupervisedPerson.SupervisedPersonName, Latitude = @t.pt?.Latitude, Longitude = @t.pt?.Longitude, Address = @t.pt?.Place, Gender = @t.d.AppCaseSupervisedPerson.Gender, Avatar = userAvatarList.FirstOrDefault(w => w.UserId == @t.d.AppCaseSupervisedPerson!.SupervisedPersonId)?.Avatar, CaseTypeId = @t.d.AppCaseManagement.CaseTypeId, CaseProgress = @t.d.AppCaseManagement.CaseProgress, PrivacyLevel = @t.d.AppCaseSupervisedPerson.PrivacyLevel }).ToList(); rtn = rtn.Distinct((x, y) => x.CaseId == y.CaseId && x.UserId == y.UserId && x.Latitude == y.Latitude && x.Longitude == y.Longitude) .ToList(); //预警总次数 var earlyWarning = _appEarlyWarningRepository.AsQueryable(false, true); var dictList = await _appDictionaryService.GetDicByDicIds(new BatchIdsInput() { Ids = rtn.Select(w => w.CaseTypeId).ToList() }); foreach (var item in rtn) { item.TotalEarlyWarningCount = item.AlertType = earlyWarning.Where(w => w.SupervisedPersonId == item.UserId).Where(w => w.CaseId == item.CaseId).Count(); item.AlertTypeLevelRules = dictList.FirstOrDefault(w => w.Id == item.CaseTypeId)?.Value; } //返回结果 return rtn; } #endregion Private } }