Merge branch 'feature/feat-efence'
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
<Project Path="Src\Dlhis.Message\Dlhis.Message.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Scheduled/">
|
||||
<Project Path="Src\Dlhis.Dormitory.Api\Dlhis.Dormitory.Api.csproj" Type="Classic C#" />
|
||||
<Project Path="Src\Dlhis.ScheduledTask\Dlhis.ScheduledTask.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Sys/">
|
||||
|
||||
17
Src/Dlhis.Dormitory.Api/Dlhis.Dormitory.Api.csproj
Normal file
17
Src/Dlhis.Dormitory.Api/Dlhis.Dormitory.Api.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Kurisu.RemoteCall" Version="0.4.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Response\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
27
Src/Dlhis.Dormitory.Api/DormitoryRemoteCallResultHandler.cs
Normal file
27
Src/Dlhis.Dormitory.Api/DormitoryRemoteCallResultHandler.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Net;
|
||||
using Kurisu.RemoteCall.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dlhis.Dormitory.Api;
|
||||
|
||||
public class DormitoryRemoteCallResultHandler : IRemoteCallResultHandler
|
||||
{
|
||||
public TResult Handle<TResult>(HttpStatusCode statusCode, string responseBody)
|
||||
{
|
||||
ApiResult<TResult> apiResult = JsonConvert.DeserializeObject<ApiResult<TResult>>(responseBody);
|
||||
if ((statusCode < HttpStatusCode.OK ? 0 : (statusCode <= (HttpStatusCode)299 ? 1 : 0)) != 0 && apiResult.Code == 200)
|
||||
return apiResult.Data;
|
||||
if (!string.IsNullOrEmpty(apiResult?.Message))
|
||||
throw new Exception(apiResult.Message);
|
||||
throw new HttpRequestException($"{statusCode.ToString()} {((int)statusCode).ToString()}");
|
||||
}
|
||||
|
||||
internal class ApiResult<T>
|
||||
{
|
||||
public string Message { get; set; }
|
||||
|
||||
public T Data { get; set; }
|
||||
|
||||
public int Code { get; set; }
|
||||
}
|
||||
}
|
||||
16
Src/Dlhis.Dormitory.Api/IDormitoryRoomPowerSwitchApi.cs
Normal file
16
Src/Dlhis.Dormitory.Api/IDormitoryRoomPowerSwitchApi.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Dlhis.Dormitory.Api.Request;
|
||||
using Kurisu.RemoteCall.Attributes;
|
||||
|
||||
namespace Dlhis.Dormitory.Api;
|
||||
|
||||
[RequestLog]
|
||||
[RequestResultHandler(typeof(DormitoryRemoteCallResultHandler))]
|
||||
[EnableRemoteClient(Name = "dormitory-service", BaseUrl = "https://apartment.jinkosolar.com/pcapi")]
|
||||
public interface IDormitoryRoomPowerSwitchApi
|
||||
{
|
||||
[Post("/api/Energy/DhIccElectricityControl")]
|
||||
Task SwitchAsync(PowerSwitchRequest request);
|
||||
|
||||
[Get("/api/Users/GetDormitoryInfoByUserCode")]
|
||||
Task<T> GetUserRoomInfoAsync<T>(string userCode);
|
||||
}
|
||||
21
Src/Dlhis.Dormitory.Api/Request/PowerSwitchRequest.cs
Normal file
21
Src/Dlhis.Dormitory.Api/Request/PowerSwitchRequest.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dlhis.Dormitory.Api.Request;
|
||||
|
||||
public class PowerSwitchRequest
|
||||
{
|
||||
public PowerSwitchRequest(string roomid, int power)
|
||||
{
|
||||
this.RoomId = roomid;
|
||||
this.Power = power;
|
||||
}
|
||||
|
||||
[JsonProperty("roomid")]
|
||||
public string RoomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0 断电 1 上电
|
||||
/// </summary>
|
||||
[JsonProperty("power")]
|
||||
public int Power { get; set; }
|
||||
}
|
||||
@@ -10,6 +10,6 @@ public class DormitoryRoomPersonEntity : SugarBaseEntity, ISoftDeleted
|
||||
public string RoomId { get; set; }
|
||||
public string UserCode { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public bool? In { get; set; }
|
||||
public bool In { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Dlhis.ScheduledTask.DeviceUploadLog.EventBus.Message;
|
||||
using Kurisu.AspNetCore.EventBus.Abstractions.Handler;
|
||||
|
||||
namespace Dlhis.ScheduledTask.DeviceUploadLog.EventBus.Handler;
|
||||
|
||||
public class DormitoryPowerSwitchHandler : IAsyncChannelHandler<DormitoryPowerSwitchMessage>
|
||||
{
|
||||
public async Task InvokeAsync(IServiceProvider serviceProvider, DormitoryPowerSwitchMessage message)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Kurisu.AspNetCore.EventBus.Abstractions;
|
||||
|
||||
namespace Dlhis.ScheduledTask.DeviceUploadLog.EventBus.Message;
|
||||
|
||||
public class DormitoryPowerSwitchMessage : IAsyncChannelMessage
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Dlhis.ScheduledTask.DeviceUploadLog.Response;
|
||||
|
||||
public class DormitoryResponse
|
||||
{
|
||||
public string RoomId { get; set; }
|
||||
public string RoomNo { get; set; }
|
||||
public string HotelId { get; set; }
|
||||
|
||||
public bool MCB { get; set; }
|
||||
|
||||
public List<DormitoryPerson> Persons { get; set; }
|
||||
}
|
||||
|
||||
public class DormitoryPerson
|
||||
{
|
||||
public string UserCode { get; set; }
|
||||
public string UserName { get; set; }
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
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;
|
||||
@@ -22,18 +25,21 @@ namespace Dlhis.ScheduledTask.DeviceUploadLog.Services.Implements;
|
||||
public class DeviceUploadLogService : IDeviceUploadLogService
|
||||
{
|
||||
private readonly IDbContext _dbContext;
|
||||
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,
|
||||
IDormitoryRoomPowerSwitchApi dormitoryRoomPowerSwitchApi,
|
||||
ICurrentUser currentUser,
|
||||
IJinkoJipApi jinkoJipApi,
|
||||
ILogger<DeviceUploadLogService> logger,
|
||||
IDingTalkApi dingTalkApi)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_dormitoryRoomPowerSwitchApi = dormitoryRoomPowerSwitchApi;
|
||||
_currentUser = currentUser;
|
||||
_jinkoJipApi = jinkoJipApi;
|
||||
_logger = logger;
|
||||
@@ -44,7 +50,11 @@ public class DeviceUploadLogService : IDeviceUploadLogService
|
||||
{
|
||||
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 existsDeviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
||||
|
||||
var deviceCodes = devices.Where(x => x.DeployDirection.HasValue).Select(x => x.Code).Distinct().ToList();
|
||||
var eFenceDeviceRelations = await _dbContext.Queryable<EFenceDeviceRelationEntity>().Where(x => deviceCodes.Contains(x.DeviceCode)).ToListAsync();
|
||||
var eFenceDeviceMap = eFenceDeviceRelations.ToDictionary(x => x.DeviceCode, x => x.EFenceCode);
|
||||
|
||||
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();
|
||||
@@ -111,6 +121,11 @@ public class DeviceUploadLogService : IDeviceUploadLogService
|
||||
? DeviceUploadLogTypeEnumType.Attendance
|
||||
: DeviceUploadLogTypeEnumType.Door;
|
||||
|
||||
if (eFenceDeviceMap.TryGetValue(device.Code, out var eFenceCore))
|
||||
{
|
||||
await HandlerPowerSwitchAsync(eFenceCore, request.UserUniqueNo, device.DeployDirection.Value);
|
||||
}
|
||||
|
||||
var workGridInfo = new WorkGridInfo();
|
||||
var currentWorkGridTimePeriods = workGridTimePeriods.Where(x => x.TenantId == device.TenantId).ToList();
|
||||
var currentWorkGridSchedules = workGridSchedules.Where(x => x.UserCode == request.UserUniqueNo).ToList();
|
||||
@@ -262,6 +277,134 @@ public class DeviceUploadLogService : IDeviceUploadLogService
|
||||
await _dbContext.InsertAsync(inserts);
|
||||
}
|
||||
|
||||
|
||||
/// <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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var room = await _dbContext.Queryable<DormitoryRoomEntity>().Where(x => x.RoomId == roomInfo.RoomId).SingleAsync();
|
||||
if (room == null)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 只在房间断电状态时才上电
|
||||
if (!room.PowerSwitch)
|
||||
{
|
||||
room.PowerSwitch = true; // 上电
|
||||
await _dbContext.UpdateAsync(room);
|
||||
await _dormitoryRoomPowerSwitchApi.SwitchAsync(new PowerSwitchRequest(room.RoomId, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Remove="log\**" />
|
||||
<Content Remove="log\**" />
|
||||
<Content Include="..\..\.dockerignore">
|
||||
<Link>.dockerignore</Link>
|
||||
</Content>
|
||||
<EmbeddedResource Remove="log\**" />
|
||||
<None Remove="log\**" />
|
||||
<Content Update="appsettings.Development.json">
|
||||
@@ -34,6 +37,7 @@
|
||||
<ProjectReference Include="..\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Constants\Dlhis.Constants.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Dormitory.Api\Dlhis.Dormitory.Api.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Entity\Dlhis.Entity.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Jip.Api\Dlhis.Jip.Api.csproj" />
|
||||
<ProjectReference Include="..\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj" />
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
# 请参阅 https://aka.ms/customizecontainer 以了解如何自定义调试容器,以及 Visual Studio 如何使用此 Dockerfile 生成映像以更快地进行调试。
|
||||
|
||||
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
|
||||
# 此阶段用于生成服务项目
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
@@ -18,17 +14,16 @@ COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"]
|
||||
COPY ["Src/Dlhis.DataPermission.Model/Dlhis.DataPermission.Model.csproj", "Src/Dlhis.DataPermission.Model/"]
|
||||
COPY ["Src/Dlhis.Jip.Api/Dlhis.Jip.Api.csproj", "Src/Dlhis.Jip.Api/"]
|
||||
COPY ["Src/Dlhis.Sys.Api/Dlhis.Sys.Api.csproj", "Src/Dlhis.Sys.Api/"]
|
||||
RUN dotnet restore "./Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj"
|
||||
COPY ["Src/Dlhis.Dormitory.Api/Dlhis.Dormitory.Api.csproj", "Src/Dlhis.Dormitory.Api/"]
|
||||
RUN dotnet restore "Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/Src/Dlhis.ScheduledTask"
|
||||
RUN dotnet build "./Dlhis.ScheduledTask.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
# 此阶段用于发布要复制到最终阶段的服务项目
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./Dlhis.ScheduledTask.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值)
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
|
||||
Reference in New Issue
Block a user