Files
jinko.yikatong/Src/Dlhis.ScheduledTask/DeviceUploadLog/Services/Implements/DeviceUploadLogService.cs

717 lines
33 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Dlhis.Basic.Api;
using Dlhis.Basic.Api.Requests;
using Dlhis.Constants;
using Dlhis.Dormitory.Api;
using Dlhis.Dormitory.Api.Request;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums;
using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Device.Enums;
using Dlhis.Entity.Device.Models;
using Dlhis.Entity.Dormitory.Entity;
using Dlhis.Jip.Api;
using Dlhis.Jip.Api.Requests;
using Dlhis.ScheduledTask.DeviceUploadLog.Request;
using Dlhis.ScheduledTask.DeviceUploadLog.Response;
using Kurisu.AspNetCore.Authentication.Abstractions;
using Kurisu.AspNetCore.Cache;
using Kurisu.AspNetCore.CustomClass;
using Kurisu.AspNetCore.DataAccess.Dto;
using Kurisu.AspNetCore.DataAccess.Entity;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
using Kurisu.AspNetCore.Utils.Extensions;
using SqlSugar;
namespace Dlhis.ScheduledTask.DeviceUploadLog.Services.Implements;
public class DeviceUploadLogService : IDeviceUploadLogService
{
private readonly IDbContext _dbContext;
private readonly RedisCache _redisCache;
private readonly IDormitoryRoomPowerSwitchApi _dormitoryRoomPowerSwitchApi;
private readonly ICurrentUser _currentUser;
private readonly IJinkoJipApi _jinkoJipApi;
private readonly ILogger<DeviceUploadLogService> _logger;
private readonly IDingTalkApi _dingTalkApi;
public DeviceUploadLogService(IDbContext dbContext,
RedisCache redisCache,
IDormitoryRoomPowerSwitchApi dormitoryRoomPowerSwitchApi,
ICurrentUser currentUser,
IJinkoJipApi jinkoJipApi,
ILogger<DeviceUploadLogService> logger,
IDingTalkApi dingTalkApi)
{
_dbContext = dbContext;
_redisCache = redisCache;
_dormitoryRoomPowerSwitchApi = dormitoryRoomPowerSwitchApi;
_currentUser = currentUser;
_jinkoJipApi = jinkoJipApi;
_logger = logger;
_dingTalkApi = dingTalkApi;
}
public async Task UploadLogsAsync(List<DeviceUploadLogUploadRequest> requests)
{
var deviceUniqueNos = requests.Select(x => x.DeviceUniqueNo).Distinct().ToList();
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => deviceUniqueNos.Contains(x.UniqueNo)).ToListAsync();
var existsDeviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
var deviceCodeInEFenceMap = await GetDeviceCodeInEFencesAsync(devices.Select(x => x.Code).ToList());
var userCodes = requests.Where(x => x.UserUniqueNo.IsPresent()).Select(x => x.UserUniqueNo).Distinct().ToList();
var gainfo1 = await _dbContext.Queryable<GainfoEntity>().Where(x => userCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name, x.Type }).ToListAsync();
var gainfo2 = await _dbContext.Queryable<GainfoEntity>().AS("GainfoLeave").Where(x => userCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name, x.Type }).ToListAsync();
var gainfoCardNos = requests.Where(x => x.CardNo.IsPresent() && x.UserUniqueNo != x.CardNo).Select(x => x.CardNo).Distinct().ToList();
var gainfo3 = await _dbContext.Queryable<GainfoEntity>().Where(x => gainfoCardNos.Contains(x.Code)).Select(x => new { x.Code, x.Name, x.Type }).ToListAsync();
var gainfos = gainfo1.Concat(gainfo2).Concat(gainfo3).DistinctBy(x => x.Code).ToList();
var userCodes2 = gainfos.Select(x => x.Code).Distinct().ToList();
var factories = devices.Select(x => x.TenantId).Distinct().ToList();
var workGridTimePeriods = await _dbContext.Queryable<WorkGridTimePeriodEntity>()
.Where(x => factories.Contains(x.TenantId))
.Select(x => new
{
x.Type,
x.Start,
x.End,
x.Before,
x.After,
x.TenantId
})
.ToListAsync();
var min = DateOnly.FromDateTime(requests.Min(x => x.RaiseDateTime)).AddDays(-1);
var max = DateOnly.FromDateTime(requests.Max(x => x.RaiseDateTime));
var workGridSchedules = await _dbContext.Queryable<WorkGridScheduleEntity>()
.Where(x => x.Date >= min && x.Date <= max && userCodes2.Contains(x.UserCode))
.Select(x => new
{
x.UserCode,
x.WorkGridCode,
x.Date,
x.PeriodType
})
.ToListAsync();
var workGrids = await GetAllWorkGridAsync();
var workGridUsers = await _dbContext.Queryable<WorkGridUserEntity>().Where(x => userCodes2.Contains(x.UserCode)).ToListAsync();
var inserts = new List<DeviceUploadLogEntity>();
foreach (var request in requests.Where(x => existsDeviceUniqueNos.Contains(x.DeviceUniqueNo)))
{
var device = devices.First(x => x.UniqueNo == request.DeviceUniqueNo);
//智能空开判断
if (deviceCodeInEFenceMap.TryGetValue(device.Code, out var fence))
{
await HandlerPowerSwitchAsync(fence.Code, request.UserUniqueNo, fence.DirectionType);
}
if (await _dbContext.Queryable<DeviceUploadLogEntity>().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo
&& x.SerialNo == request.SerialNo
&& x.RaiseDateTime == request.RaiseDateTime).AnyAsync())
{
continue;
}
var currentGainfo = gainfos.FirstOrDefault(x => x.Code == request.UserUniqueNo);
var userType = currentGainfo?.Type;
var needUpload = ((userType is GainfoUserTypeEnumType.Normal or GainfoUserTypeEnumType.SecurityWhite)
&& (device.Type == DeviceTypeEnumType.Attendance || (device.Type == DeviceTypeEnumType.Door && device.AsAttendance)));
var dataType = device.Type == DeviceTypeEnumType.Attendance
? DeviceUploadLogTypeEnumType.Attendance
: DeviceUploadLogTypeEnumType.Door;
var workGridInfo = new WorkGridInfo();
var currentWorkGridTimePeriods = workGridTimePeriods.Where(x => x.TenantId == device.TenantId).ToList();
var currentWorkGridSchedules = workGridSchedules.Where(x => x.UserCode == request.UserUniqueNo).ToList();
var currentWorkGridUser = workGridUsers.FirstOrDefault(x => x.UserCode == request.UserUniqueNo); //可能被删除,但还存在当天的排班
if (needUpload && currentWorkGridTimePeriods.Any() && (currentWorkGridUser != null || currentWorkGridSchedules.Any()))
{
workGridInfo.TimeSetting = currentWorkGridTimePeriods.Select(x => new
{
Type = x.Type.GetDescription(),
x.Before,
x.Start,
x.End,
x.After,
x.TenantId
}).ToList();
if (currentWorkGridUser != null)
{
var currentWorkGrid = workGrids.First(x => x.Code == currentWorkGridUser.WorkGridCode);
workGridInfo.WorkGrid = new WorkGridInfoDetail
{
WorkGridCode = currentWorkGrid.Code,
WorkGridName = currentWorkGrid.Name,
LeaderUserCode = currentWorkGrid.LeaderUserCode
};
}
var currentDate = request.RaiseDateTime.Date;
var currentDateOnly = DateOnly.FromDateTime(currentDate);
//白班判断
var dayTimePeriod = currentWorkGridTimePeriods.FirstOrDefault(x => x.Type == WorkGridTimePeriodEnumType.Day);
if (dayTimePeriod != null)
{
var currentDayWorkGridSchedule = currentWorkGridSchedules.FirstOrDefault(x => x.PeriodType == WorkGridTimePeriodEnumType.Day && x.Date == currentDateOnly);
if (currentDayWorkGridSchedule != null)
{
var start = currentDate.Add(dayTimePeriod.Start.AddMinutes(-dayTimePeriod.Before).ToTimeSpan());
var end = currentDate.Add(dayTimePeriod.End.AddMinutes(dayTimePeriod.After).ToTimeSpan());
if (request.RaiseDateTime >= start && request.RaiseDateTime <= end)
{
workGridInfo.PeriodType = WorkGridTimePeriodEnumType.Day;
var currentWorkGrid = workGrids.First(x => x.Code == currentDayWorkGridSchedule.WorkGridCode);
workGridInfo.WorkGrid = new WorkGridInfoDetail
{
WorkGridCode = currentWorkGrid.Code,
WorkGridName = currentWorkGrid.Name,
LeaderUserCode = currentWorkGrid.LeaderUserCode
};
}
}
}
//晚班判断
var nightTimePeriod = currentWorkGridTimePeriods.FirstOrDefault(x => x.Type == WorkGridTimePeriodEnumType.Night);
if (nightTimePeriod != null)
{
var currentNightWorkGridSchedules = currentWorkGridSchedules
.Where(x => x.PeriodType == WorkGridTimePeriodEnumType.Night)
.Where(x => x.Date == currentDateOnly || x.Date == currentDateOnly.AddDays(-1))
.ToList();
if (currentNightWorkGridSchedules.Any())
{
var startTime = nightTimePeriod.Start.AddMinutes(-nightTimePeriod.Before);
var endTime = nightTimePeriod.End.AddMinutes(nightTimePeriod.After);
if (currentNightWorkGridSchedules.Any(x => x.Date == currentDateOnly))
{
var start = currentDateOnly.ToDateTime(startTime);
var end = currentDateOnly.ToDateTime(new TimeOnly(23, 59, 59, 999));
if (request.RaiseDateTime >= start && request.RaiseDateTime <= end)
{
workGridInfo.PeriodType = WorkGridTimePeriodEnumType.Night;
var currentWorkGrid = workGrids.First(x => x.Code == currentNightWorkGridSchedules.First(p => p.Date == currentDateOnly).WorkGridCode);
workGridInfo.WorkGrid = new WorkGridInfoDetail
{
WorkGridCode = currentWorkGrid.Code,
WorkGridName = currentWorkGrid.Name,
LeaderUserCode = currentWorkGrid.LeaderUserCode
};
}
}
if (currentNightWorkGridSchedules.Any(x => x.Date == currentDateOnly.AddDays(-1)))
{
var start = currentDateOnly.AddDays(-1).ToDateTime(startTime);
var end = currentDateOnly.ToDateTime(endTime);
if (request.RaiseDateTime >= start && request.RaiseDateTime <= end)
{
workGridInfo.PeriodType = WorkGridTimePeriodEnumType.Night;
var currentWorkGrid = workGrids.First(x => x.Code == currentNightWorkGridSchedules.First(p => p.Date == currentDateOnly.AddDays(-1)).WorkGridCode);
workGridInfo.WorkGrid = new WorkGridInfoDetail
{
WorkGridCode = currentWorkGrid.Code,
WorkGridName = currentWorkGrid.Name,
LeaderUserCode = currentWorkGrid.LeaderUserCode
};
}
}
}
}
needUpload = workGridInfo.WorkGrid == null || workGridInfo.PeriodType.HasValue;
workGridInfo.IsError = !needUpload;
if (!needUpload)
{
try
{
await _dingTalkApi.SendWorkMessageByWorkGridAsync(new JinkoSendWorkMessageRequest
{
Content = $"{workGridInfo.WorkGrid.WorkGridName}的网格长,你好,检测到你网格中 {currentGainfo.Name}({currentGainfo.Code}){request.RaiseDateTime.ToString("yyyy年MM月dd日")}未排班,但是有考勤记录,请前往系统处理!",
WorkCodes = new List<string> { workGridInfo.WorkGrid.LeaderUserCode }
});
await _dingTalkApi.SendWorkMessageByWorkGridAsync(new JinkoSendWorkMessageRequest
{
Content = $"{currentGainfo.Name}({currentGainfo.Code},检测到你在{workGridInfo.WorkGrid.WorkGridName}网格中,当日未排班,考勤记录不生效,请立即联系网格长",
WorkCodes = new List<string> { currentGainfo.Code }
});
}
catch (Exception e)
{
_logger.LogError(e, "推送信息错误schedule:{error}", e.Message);
}
}
}
inserts.Add(new DeviceUploadLogEntity
{
DeviceCode = device.Code,
DeviceUniqueNo = request.DeviceUniqueNo,
UserUniqueNo = request.UserUniqueNo,
UserType = userType,
RaiseDateTime = request.RaiseDateTime,
SerialNo = request.SerialNo ?? string.Empty,
Type = dataType,
NeedUpload = needUpload,
TenantId = device.TenantId,
Status = request.Status ?? true,
Image = request.Image,
WorkGridInfo = workGridInfo.ToJson(),
CreatedBy = 1,
ModifiedBy = 1
});
}
await _dbContext.InsertAsync(inserts);
}
private async Task<List<WorkGridEntity>> GetAllWorkGridAsync()
{
_dbContext.Client.QueryFilter.ClearAndBackup<ISoftDeleted>();
try
{
return await _dbContext.Queryable<WorkGridEntity>().ToListAsync();
}
finally
{
_dbContext.Client.QueryFilter.Restore();
}
}
private async Task<Dictionary<Guid, EFenceEntity>> GetDeviceCodeInEFencesAsync(List<Guid> deviceCodes)
{
var eFenceDeviceRelations = await _dbContext.Queryable<EFenceDeviceRelationEntity>()
.Where(x => deviceCodes.Contains(x.DeviceCode))
.ToListAsync();
var eFenceCodes = eFenceDeviceRelations.Select(x => x.EFenceCode).Distinct().ToList();
var eFences = await _dbContext.Queryable<EFenceEntity>().Where(x => eFenceCodes.Contains(x.Code)).ToListAsync();
//二次过滤
var eFenceCodesNew = eFences.Select(x => x.Code).Distinct().ToList();
eFenceDeviceRelations = eFenceDeviceRelations.Where(x => eFenceCodesNew.Contains(x.EFenceCode)).ToList();
return eFenceDeviceRelations.ToDictionary(x => x.DeviceCode, x => eFences.First(y => y.Code == x.EFenceCode));
}
/// <summary>
/// 宿舍只能空开触发
/// </summary>
/// <param name="eFenceCode"></param>
/// <param name="userCode"></param>
/// <param name="directionType"></param>
private async Task HandlerPowerSwitchAsync(Guid eFenceCode, string userCode, DeviceDeployDirectionEnumType directionType)
{
try
{
//调用获取人员信息接口
var roomInfo = await _dormitoryRoomPowerSwitchApi.GetUserRoomInfoAsync<DormitoryResponse>(userCode);
if (!roomInfo.MCB)
{
_logger.LogInformation("MCB未开启, userCode:{userCode} directionType:{directionType}", userCode, directionType);
return;
}
var room = await _dbContext.Queryable<DormitoryRoomEntity>().Where(x => x.RoomId == roomInfo.RoomId).SingleAsync();
if (room == null)
{
//这里会有并发问题,加分布式锁
await using var lockHandler = await _redisCache.LockAsync("dormitory_room_key_" + roomInfo.RoomId, TimeSpan.FromSeconds(10), retryCount: 5);
if (lockHandler.Acquired)
{
room = new DormitoryRoomEntity
{
EFenceCode = eFenceCode,
RoomId = roomInfo.RoomId,
RoomNo = roomInfo.RoomNo,
HotelId = roomInfo.HotelId,
PowerSwitch = true
};
await _dbContext.InsertAsync(room);
var personEntities = roomInfo.Persons.Select(x => new DormitoryRoomPersonEntity
{
RoomId = roomInfo.RoomId,
UserCode = x.UserCode,
UserName = x.UserName,
In = true,
IsDeleted = false
})
.ToList();
await _dbContext.InsertAsync(personEntities);
var person = await _dbContext.Queryable<DormitoryRoomPersonEntity>()
.Where(x => x.RoomId != roomInfo.RoomId && x.UserCode == userCode)
.FirstAsync();
if (person != null)
{
await _dbContext.DeleteAsync(person);
}
}
}
else
{
var existsPersons = await _dbContext.Queryable<DormitoryRoomPersonEntity>()
.Where(x => x.RoomId == roomInfo.RoomId)
.ToListAsync();
//根据roomInfo.Persons和existsPersons不在当前房间的人
var toDeletePersons = existsPersons.Where(x => roomInfo.Persons.All(p => p.UserCode != x.UserCode)).ToList();
if (toDeletePersons.Any())
{
await _dbContext.DeleteAsync(toDeletePersons);
}
//需要新增的
var toAddPersons = roomInfo.Persons.Where(x => existsPersons.All(p => p.UserCode != x.UserCode)).ToList();
if (toAddPersons.Any())
{
var personEntities = toAddPersons.Select(x => new DormitoryRoomPersonEntity()
{
RoomId = roomInfo.RoomId,
UserCode = x.UserCode,
UserName = x.UserName,
In = true,
IsDeleted = false
}).ToList();
await _dbContext.InsertAsync(personEntities);
}
room.EFenceCode = eFenceCode;
await _dbContext.UpdateAsync(room);
}
//如果DormitoryRoomPersonEntity.in都为false,断电, 否则上电(前提是DormitoryRoomEntity.PowerSwitch==false)
// 查询房间所有人员
var persons = await _dbContext.Queryable<DormitoryRoomPersonEntity>()
.Where(x => x.RoomId == roomInfo.RoomId)
.ToListAsync();
persons.ForEach(x =>
{
if (x.UserCode == userCode)
{
x.In = directionType == DeviceDeployDirectionEnumType.Entry;
}
});
await _dbContext.UpdateAsync(persons);
// 如果所有人都不在房间,且当前房间是通电状态,则断电
if (persons.All(x => !x.In))
{
if (room.PowerSwitch)
{
room.PowerSwitch = false; // 断电
await _dbContext.UpdateAsync(room);
await _dormitoryRoomPowerSwitchApi.SwitchAsync(new PowerSwitchRequest(room.RoomId, 0));
_logger.LogInformation("房间下电{roomNo}", room.RoomNo);
}
}
else
{
// 只在房间断电状态时才上电
if (!room.PowerSwitch)
{
room.PowerSwitch = true; // 上电
await _dbContext.UpdateAsync(room);
await _dormitoryRoomPowerSwitchApi.SwitchAsync(new PowerSwitchRequest(room.RoomId, 1));
_logger.LogInformation("房间上电{roomNo}", room.RoomNo);
}
}
}
catch (Exception e)
{
_logger.LogError(e, "宿舍空开触发失败, userCode:{userCode} directionType:{directionType} error:{error}", userCode, directionType, e.Message);
}
}
public async Task<List<DeviceUploadLogResponse>> GetMyRecordsAsync(DeviceUploadLogMyRecordRequest request)
{
var jinkoCode = _currentUser.GetUserClaim(UserClaimConstants.JinkoCode) ?? string.Empty;
return await _dbContext.Queryable<DeviceUploadLogEntity>()
.LeftJoin<DeviceEntity>((log, d) => log.DeviceUniqueNo == d.UniqueNo)
.Where(log => log.UserUniqueNo == jinkoCode)
.Where(log => log.Status)
.WhereIF(request.DateTimePeriod.HasValue(), log => log.RaiseDateTime >= request.DateTimePeriod.Start && log.RaiseDateTime <= request.DateTimePeriod.End)
.Where((log, d) => d.Type == DeviceTypeEnumType.Attendance || (d.Type == DeviceTypeEnumType.Door && d.AsAttendance))
.OrderBy(log => log.RaiseDateTime)
.Select((log, d) => new DeviceUploadLogResponse
{
OriginUserUniqueNo = log.UserUniqueNo,
DeviceUniqueNo = log.DeviceUniqueNo,
Id = log.Id,
RaiseDateTime = log.RaiseDateTime,
CreateTime = log.CreateTime,
SerialNo = log.SerialNo,
DeployPlace = d.DeployPlace,
Sync = log.Sync,
Status = log.Status
})
.ToListAsync();
}
/// <inheritdoc />
public async Task ManuallyUploadAsync(List<long> requestIds)
{
var requests = await _dbContext.Queryable<DeviceUploadLogEntity>()
.LeftJoin<DeviceEntity>((x, device) => x.DeviceUniqueNo == device.UniqueNo)
.Where(x => requestIds.Contains(x.Id))
.Where(x => x.NeedUpload && x.Sync == false && (x.UserType == GainfoUserTypeEnumType.Normal || x.UserType == GainfoUserTypeEnumType.SecurityWhite))
.Select((x, device) => new UploadAttendanceRequestItem
{
Id = x.Id,
RaiseDateTime = x.RaiseDateTime,
ZNOTE = device.DeployPlace,
ZWORKCODE = x.UserUniqueNo
})
.ToListAsync();
if (requests.Any())
{
foreach (var items in requests.Chunk(500))
{
var ids = items.Select(x => x.Id).ToList();
var r = await _jinkoJipApi.UploadAttendancesAsync(new UploadAttendanceRequest { Data = items.ToList() });
if (r.OLX == "0")
{
await _dbContext.Updateable<DeviceUploadLogEntity>()
.SetColumns(x => x.Sync == true)
.SetColumns(x => x.ModifiedTime == DateTime.Now)
.Where(x => ids.Contains(x.Id))
.ExecuteCommandAsync();
}
}
}
}
/// <inheritdoc />
public async Task ManuallySetTimeInfoAsync(string deviceNo, DateTime start, DateTime end)
{
var device = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == deviceNo).SingleAsync();
(device.Type != DeviceTypeEnumType.Attendance && device.Type != DeviceTypeEnumType.Door).ThrowIfTrue("不支持该设备类型");
var exists = await _dbContext.Queryable<DeviceUploadLogManuallyEntity>().Where(x => x.DeviceNo == deviceNo).Where(x => x.IsFinished == false).AnyAsync();
exists.ThrowIfTrue("已存在配置尚未完成");
await _dbContext.InsertAsync(new DeviceUploadLogManuallyEntity
{
DeviceNo = deviceNo,
Start = start,
End = end,
IsFinished = false
});
}
public async Task QiaoqiaoGaoshiqingAsync(DeviceUploadLogSecretAddRequest request)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == request.UserCode).SingleAsync();
gainfo.ThrowIfNull("人员不存在");
var device = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.DeviceUniqueNo).SingleAsync();
await _dbContext.InsertAsync(new DeviceUploadLogEntity
{
DeviceUniqueNo = device.UniqueNo,
UserUniqueNo = request.UserCode,
UserType = gainfo.Type,
RaiseDateTime = request.RaiseDateTime,
Type = device.Type == DeviceTypeEnumType.Attendance
? DeviceUploadLogTypeEnumType.Attendance
: DeviceUploadLogTypeEnumType.Door,
NeedUpload = true,
Sync = false,
SerialNo = string.Empty,
DeviceCode = device.Code,
TenantId = device.TenantId,
Status = true,
Image = null,
CreatedBy = 1,
ModifiedBy = 1
});
}
/// <inheritdoc />
public async Task Test()
{
var before60Days = DateTime.Today.AddDays(-60).AddSeconds(1);
var data = await _dbContext.Queryable<DeviceUploadLogEntity>().Where(x => x.RaiseDateTime < before60Days).OrderBy(x => x.Id).ToPageListAsync(1, 500);
if (data.Any())
{
await _dbContext.DeleteReallyAsync(data);
const string tableName = "deviceuploadlog_20250107";
foreach (var item in data)
{
item.Id = 0;
}
await _dbContext.Client.Insertable(data).AS(tableName).ExecuteCommandAsync();
}
}
public async Task<DateTimePeriod> GetDeviceUploadRecordSettingAsync(string deviceNo)
{
var start = await _dbContext.Queryable<DeviceUploadLogEntity>()
.Where(x => x.DeviceUniqueNo == deviceNo)
.Select(x => SqlFunc.AggregateMax(x.RaiseDateTime))
.SingleAsync();
//0001-01-01 00:00:00
return new DateTimePeriod
{
Start = start,
End = DateTime.Now.AddDays(1)
};
}
public async Task<Pagination<DeviceUploadLogUserResponse>> GetUserPageAsync(DeviceUploadLogUserPageRequest request)
{
var r = await _dbContext.Queryable<DeviceUploadLogEntity>()
.LeftJoin<DeviceEntity>((x, device) => x.DeviceUniqueNo == device.UniqueNo)
.LeftJoin<GainfoEntity>((x, device, ga) => x.UserUniqueNo == ga.Code)
.WhereIF(request.SearchDateTimePeriod.HasValue(), x => x.RaiseDateTime >= request.SearchDateTimePeriod.Start
&& x.RaiseDateTime <= request.SearchDateTimePeriod.End)
.Where((x, device) => x.NeedUpload)
.WhereIF(request.Search.IsPresent(), (x, device, ga) =>
x.UserUniqueNo == request.Search
|| x.DeviceUniqueNo == request.Search
)
.OrderBy(x => x.RaiseDateTime, OrderByType.Desc)
.Select((x, device, ga) => new DeviceUploadLogUserResponse
{
Id = x.Id,
OriginUserUniqueNo = x.UserUniqueNo,
DeviceUniqueNo = x.DeviceUniqueNo,
RaiseDateTime = x.RaiseDateTime,
CreateTime = x.CreateTime,
SerialNo = x.SerialNo,
UserNo = ga.No,
UserCode = ga.Code,
UserName = ga.Name,
DeployPlace = device.DeployPlace,
NeedUpload = x.NeedUpload,
Sync = x.Sync,
Status = x.Status,
WorkGridInfo = x.WorkGridInfo
}).ToPageListAsync(request.PageIndex, request.PageSize);
return new Pagination<DeviceUploadLogUserResponse>
{
PageIndex = request.PageIndex,
PageSize = request.PageSize,
Total = 0,
Data = r
};
}
public async Task<Pagination<DeviceUploadLogResponse>> GetPageAsync(DeviceUploadLogPageRequest request)
{
var type = request.Type switch
{
DeviceTypeEnumType.Attendance => DeviceUploadLogTypeEnumType.Attendance,
DeviceTypeEnumType.Door => DeviceUploadLogTypeEnumType.Door,
_ => throw new UserFriendlyException("不支持当前设备类型")
};
var userTypes = new List<GainfoUserTypeEnumType?> { request.UserType };
if (request.UserType == GainfoUserTypeEnumType.Normal)
{
userTypes.Add(GainfoUserTypeEnumType.SecurityWhite);
}
var dayBefore60 = DateTime.Today.AddDays(-60);
if (request.SearchDateTimePeriod.Start <= dayBefore60 && request.SearchDateTimePeriod.End > dayBefore60)
{
throw new UserFriendlyException("请勿跨归档数据查询");
}
var isArchivedSearch = request.SearchDateTimePeriod.End <= dayBefore60;
var table = isArchivedSearch
? _dbContext.Queryable<DeviceUploadLogEntity>().AS("deviceuploadlog_20250107")
: _dbContext.Queryable<DeviceUploadLogEntity>();
var isNormalSearch = !userTypes.Contains(GainfoUserTypeEnumType.Outsource);
var isOutsourceSearch = userTypes.Contains(GainfoUserTypeEnumType.Outsource);
var r = await table
.LeftJoin<DeviceEntity>((x, device) => x.DeviceUniqueNo == device.UniqueNo)
.LeftJoin<GainfoEntity>((x, device, ga) => x.UserUniqueNo == ga.Code)
.LeftJoin<OutsourceEntity>((x, device, ga, os) => x.UserUniqueNo == os.Code)
.LeftJoin<GainfoEntity>((x, device, ga, os, gaSap) => gaSap.Code == os.SapCode)
.Where(x => x.RaiseDateTime >= request.SearchDateTimePeriod.Start && x.RaiseDateTime <= request.SearchDateTimePeriod.End)
.Where((x, device) => x.Type == type && !SqlFunc.IsNullOrEmpty(x.UserType) && userTypes.Contains(x.UserType))
.WhereIF(request.Sync.HasValue, x => x.Sync == request.Sync)
.WhereIF(isOutsourceSearch && request.Search.IsPresent(), (x, device, ga, os) =>
x.UserUniqueNo == request.Search
|| x.DeviceUniqueNo == request.Search
|| os.Supplier == request.Search
|| os.SapCode == request.Search
)
.WhereIF(isNormalSearch && request.UserCode.IsPresent(), (x, device, ga, os) => x.UserUniqueNo == request.UserCode)
.WhereIF(isNormalSearch && request.DeviceUniqueNo.IsPresent(), (x, device, ga, os) => x.DeviceUniqueNo == request.DeviceUniqueNo)
.WhereIF(request.Search.IsPresent() && isNormalSearch, (x, device, ga, os) =>
x.UserUniqueNo == request.Search
|| x.DeviceUniqueNo == request.Search
)
.OrderBy(x => x.RaiseDateTime, OrderByType.Desc)
.Select((x, device, ga, os, gaSap) => new DeviceUploadLogResponse
{
Id = x.Id,
OriginUserUniqueNo = x.UserUniqueNo,
OutsourceSupplier = os.Supplier,
SapUserCode = os.SapCode,
SapUserName = gaSap.Name,
DeviceUniqueNo = x.DeviceUniqueNo,
RaiseDateTime = x.RaiseDateTime,
CreateTime = x.CreateTime,
SerialNo = x.SerialNo,
UserNo = ga.No,
UserCode = x.UserUniqueNo,
UserName = ga.Name,
DeployPlace = device.DeployPlace,
NeedUpload = x.NeedUpload,
Sync = x.Sync,
Status = x.Status,
WorkGridInfo = x.WorkGridInfo
}).ToPageListAsync(request.PageIndex, request.PageSize);
var userCodes = r.Where(x => x.UserName.IsEmpty()).Select(x => x.UserCode).Distinct().ToList();
var gainfoLeaves = await _dbContext.Queryable<GainfoLeaveEntity>().Where(x => userCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name }).ToListAsync();
r.ForEach(item =>
{
if (item.UserName.IsEmpty())
{
item.UserName = gainfoLeaves.FirstOrDefault(x => x.Code == item.UserCode)?.Name;
}
});
return new Pagination<DeviceUploadLogResponse>
{
PageIndex = request.PageIndex,
PageSize = request.PageSize,
Total = 0,
Data = r
};
}
}