转移第三方接口

pull/26/head
刘鑫 4 months ago
parent 6c43874569
commit d7a1e13cee
  1. 8
      WeiCloud.Fusion/AlarmService/Alarm.Application/Alarm.Application.csproj
  2. 2
      WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/AppHost.cs
  3. 1
      WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/Manage.AppHost.AppHost.csproj
  4. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/BaseModels/ApiResult.cs
  5. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/BaseModels/LoggerWarp.cs
  6. 46
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/BaseModels/SafeEnum.cs
  7. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/ReadMe.md
  8. 1
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/SafetyFirePro/ReadMe.md
  9. 23
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/SafetyFirePro/RequestDto/SunPalaceBoardReqDto.cs
  10. 242
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/SafetyFirePro/ResponseDto/SunPalaceBoardResDto.cs
  11. 4
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/MqttClient/MQTTClient.cs
  12. 160
      WeiCloud.Fusion/ParkingLotService/ParkLotInfoService/ParkingLotDataService.cs
  13. 46
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Controllers/PuTianSuYuan/SunPalaceBoardFacilityController.cs
  14. 35
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Controllers/ShenZhouShengAn/SunPalaceBoardSafetyController.cs
  15. 17
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Infrastructure/AutoMapperProfile.cs
  16. 31
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Infrastructure/ConfigureAutofac.cs
  17. 57
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/NLog.config
  18. 121
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Program.cs
  19. 8
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Properties/launchSettings.json
  20. 19
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/Startup.cs
  21. 15
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/ThirdPartyServices.API.csproj
  22. 14
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.API/appsettings.json
  23. 68
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.Application/ShenZhouShengAn/RequestDto/ThirdPartyProviderQueryDto.cs
  24. 38
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.Application/ShenZhouShengAn/ResponseDto/ThirdPartyProviderResDto.cs
  25. 7
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.Application/ThirdPartyServices.Application.csproj
  26. 2472
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/PuTianSuYuan/AssetWebClientService.cs
  27. 93
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/PuTianSuYuan/AssetWebContextService.cs
  28. 7
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/PuTianSuYuan/IAssetWebService.cs
  29. 12
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/PuTianSuYuan/ISunPalaceBoardFacilityService.cs
  30. 196
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/PuTianSuYuan/SunPalaceBoardFacilityService.cs
  31. 16
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/ShenZhouShengAn/ISunPalaceBoardSafetyService.cs
  32. 39
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/ShenZhouShengAn/IThirdPartyProviderService.cs
  33. 127
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/ShenZhouShengAn/SunPalaceBoardSafetyService.cs
  34. 170
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/ShenZhouShengAn/ThirdPartyProviderService.cs
  35. 12
      WeiCloud.Fusion/ThirdPartyServices/ThirdPartyServices.DomainService/ThirdPartyServices.DomainService.csproj
  36. 1
      WeiCloud.Fusion/VideoService/Video.API/Controllers/DaHua/VideoManageController.cs
  37. 4
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/IRootVideoPlaybackService.cs
  38. 4
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/RootVideoPlaybackService.cs

@ -7,8 +7,12 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="RequestDto\" />
<Folder Include="ResponeDto\" />
<Compile Remove="RequestDto\**" />
<Compile Remove="ResponeDto\**" />
<EmbeddedResource Remove="RequestDto\**" />
<EmbeddedResource Remove="ResponeDto\**" />
<None Remove="RequestDto\**" />
<None Remove="ResponeDto\**" />
</ItemGroup>
</Project>

@ -5,10 +5,12 @@ var apiService = builder.AddProject<Projects.Manage_AppHost_ApiService>("apiserv
var videoapi = builder.AddProject<Projects.Video_API>("videoapi");
var alarmapi = builder.AddProject<Projects.AlarmService_API>("alarmapi");
var thirdpartyapi = builder.AddProject<Projects.ThirdPartyServices_API>("thirdpartyapi");
builder.AddProject<Projects.Manage_AppHost_Web>("webfrontend")
.WithReference(videoapi)
.WithReference(alarmapi)
.WithReference(thirdpartyapi)
.WithExternalHttpEndpoints()
.WithHttpHealthCheck("/health")

@ -13,6 +13,7 @@
<ItemGroup>
<ProjectReference Include="..\..\AlarmService\AlarmService.API\AlarmService.API.csproj" />
<ProjectReference Include="..\..\Common.SharedService\Common.Shared.API\Common.Shared.API.csproj" />
<ProjectReference Include="..\..\ThirdPartyServices\ThirdPartyServices.API\ThirdPartyServices.API.csproj" />
<ProjectReference Include="..\..\VideoService\Video.API\Video.API.csproj" />
<ProjectReference Include="..\Manage.AppHost.ApiService\Manage.AppHost.ApiService.csproj" />
<ProjectReference Include="..\Manage.AppHost.Web\Manage.AppHost.Web.csproj" />

@ -1,4 +1,4 @@
namespace WeiCloud.Core.BaseModels
namespace Common.Shared.Application.BaseModels
{
public class ApiResult<T>
{

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace WeiCloud.Core.BaseModels
namespace Common.Shared.Application.BaseModels
{
public class LoggerWarp
{

@ -0,0 +1,46 @@
using System.ComponentModel;
namespace Common.Shared.Application.BaseModels
{
/// <summary>
/// 获取事后分析警情指标请求实体中日期类型的枚举
/// </summary>
public enum QueryTimeEnum
{
/// <summary>
/// 按日
/// </summary>
[Description("按日")]
Daily = 1,
/// <summary>
/// 按月
/// </summary>
[Description("按月")]
Monthly = 2,
/// <summary>
/// 按年
/// </summary>
[Description("按年")]
Yearly = 3,
/// <summary>
/// 自定义
/// </summary>
[Description("自定义")]
Custom = 0,
/// <summary>
/// 小时
/// </summary>
[Description("小时")]
Hours = 5,
/// <summary>
/// 周
/// </summary>
[Description("周")]
Week = 6,
}
}

@ -0,0 +1,2 @@
# 这是大华公司的ICC平台,涉及到的请求和响应DTO类
https://open-icc.dahuatech.com/#/home

@ -0,0 +1 @@
*这是安消项目下的请求和响应DTO文件夹,这里不需要根据某个第三方来切割,后续可以根据项目来切割不同的文件夹*

@ -0,0 +1,23 @@
using Common.Shared.Application.BaseModels;
namespace Common.Shared.Application.SafetyFirePro.RequestDto
{
/// <summary>
/// 查询基类
/// </summary>
public class SecSituationQueryDto
{
/// <summary>
/// 查询时间
/// </summary>
public int? QueryTimeType { get; set; } = (int)QueryTimeEnum.Daily;
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
/// <summary>
/// 项目id
/// </summary>
public long? ProjectId { get; set; }
}
}

@ -0,0 +1,242 @@
using System.Text.Json.Serialization;
namespace Common.Shared.Application.SafetyFirePro.ResponseDto
{
#region 太阳宫看板-综合安全态势返回体
/// <summary>
/// 第三方风险点数据
/// </summary>
public class DangerRiskAreaResDto
{
/// <summary>
/// 获得单位风险点汇总数据
/// </summary>
[JsonPropertyName("existingRisks")]
public List<ProductionRiskStatsResDto>? ProductionRiskStats { get; set; }
/// <summary>
/// 隐患数据
/// </summary>
public List<DangerInfo>? DangerInfos { get; set; }
}
/// <summary>
/// 生产风险识别
/// </summary>
public class ProductionRiskStatsResDto
{
/// <summary>
/// 风险名称(如 "重大风险")
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; } //
/// <summary>
/// 风险数量
/// </summary>
[JsonPropertyName("count")]
public int Count { get; set; } //
/// <summary>
/// 颜色编码(如 "#ff0000")
/// </summary>
[JsonPropertyName("color")]
public string Color { get; set; } //
}
/// <summary>
/// 安全隐患信息列表
/// </summary>
public class DangerInfo
{
/// <summary>
/// 隐患状态
/// </summary>
public string? Status { get; set; } //隐患状态:0待核查,1待整改,2待验收,3待排查
/// <summary>
/// 隐患状态数量
/// </summary>
public int StatusCount { get; set; } = 0;
/// <summary>
/// 隐患等级数量
/// </summary>
public int DangerLevelCount { get; set; } = 0;
}
#endregion 太阳宫看板-综合安全态势返回体
#region 太阳宫看板-设备设施态势返回体
/// <summary>
/// 资产仪表盘
/// </summary>
public class AssetOverviewResDto
{
/// <summary>
/// 排序
/// </summary>
public int OrderBy { get; set; } = 1;
/// <summary>
/// 资产名字
/// </summary>
public string Name { get; set; } = default!;
/// <summary>
/// 资产总数
/// </summary>
public double TotalAssetCount { get; set; }
/// <summary>
/// 所有百分比的
/// </summary>
public double? TotalAssetCountGrowthRate { get; set; }
///// <summary>
///// 总资产数
///// </summary>
//public int TotalAssetCount { get; set; }
///// <summary>
///// 总资产数较上月增长百分比(如 5.2 表示增长 5.2%)
///// </summary>
//public double TotalAssetCountGrowthRate { get; set; }
///// <summary>
///// 总资产价值(单位:万元)
///// </summary>
//public double TotalAssetValue { get; set; }
///// <summary>
///// 总资产价值较上月增长百分比
///// </summary>
//public decimal TotalAssetValueGrowthRate { get; set; }
///// <summary>
///// 资产盘点进度(如 0.92 表示 92%)
///// </summary>
//public decimal InventoryProgressRate { get; set; }
///// <summary>
///// 资产分布楼层数
///// </summary>
//public int AssetFloorCoverage { get; set; }
///// <summary>
///// 在保资产数量
///// </summary>
//public int InsuredAssetCount { get; set; }
///// <summary>
///// 在保资产较上月减少百分比(如 -2.1 表示减少 2.1%)
///// </summary>
//public decimal InsuredAssetChangeRate { get; set; }
///// <summary>
///// 待维修资产数量
///// </summary>
//public int RepairPendingAssetCount { get; set; }
///// <summary>
///// 待维修资产较上月增长百分比
///// </summary>
//public decimal RepairPendingGrowthRate { get; set; }
///// <summary>
///// 本月折旧金额(单位:元)
///// </summary>
//public decimal DepreciationThisMonth { get; set; }
///// <summary>
///// 折旧金额较上月增长百分比
///// </summary>
//public decimal DepreciationGrowthRate { get; set; }
///// <summary>
///// 今日报警数量(待处理)
///// </summary>
//public int TodayAlarmCount { get; set; }
}
/// <summary>
/// 资产类型统计返回体
/// </summary>
public class AssetTypeResDto
{
/// <summary>
/// 类型名
/// </summary>
public string AssetType { get; set; } = default!;
/// <summary>
/// 数量
/// </summary>
public int AssetCount { get; set; } = 0;
}
/// <summary>
/// 折旧率对比
/// </summary>
public class AvgDepreciationResDto
{
/// <summary>
/// 设备名
/// </summary>
public string DeviceName { get; set; } = default!;
/// <summary>
/// 折旧率
/// </summary>
public double TotalAssetCount
{
get; set;
}
}
/// <summary>
/// 资产报警分析
/// </summary>
public class AssetAlarmTrendResDto
{
/// <summary>
/// 资产名字
/// </summary>
public string? AssetName { get; set; }
/// <summary>
/// 月份
/// </summary>
public int Monthly { get; set; }
/// <summary>
/// 资产数量
/// </summary>
public int AssetCount { get; set; } = 0;
}
/// <summary>
/// 合规证件预警
/// </summary>
public class IdCardAlarmResDto
{
/// <summary>
/// 证件名称
/// </summary>
public string CardName { get; set; } = default!;
/// <summary>
/// 有效期
/// </summary>
public DateTime ValidityPeriod { get; set; } = default!;
/// <summary>
/// 剩余天数
/// </summary>
public int RemainingDays { get; set; } = 0;
}
#endregion 太阳宫看板-设备设施态势返回体
}

@ -1,8 +1,8 @@
using Microsoft.Extensions.Logging;
using Common.Shared.Application.BaseModels;
using Microsoft.Extensions.Logging;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
using WeiCloud.Core.BaseModels;
namespace Common.Shared.DomainService
{

@ -1,33 +1,21 @@
using Microsoft.AspNetCore.Components;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using ParkingLotEntity.DB;
using ParkingLotEntity.ParkingLotModelDto;
using ParkingLotEntity.ParkingLotModelDto.BaseModels;
using ParkingLotEntity.ParkingLotModels;
using Pipelines.Sockets.Unofficial.Arenas;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using WeiCloud.Core;
using WeiCloud.Utils.EncodeTools;
using WeiCloudAPP.Core;
using NewLife.Serialization;
using WeiCloud.Utils.Common;
using Microsoft.Extensions.Configuration;
using System.Net.Http;
using System.Text.Encodings.Web;
using System.Text;
using System.Net.NetworkInformation;
using NPOI.SS.UserModel;
using ParkingLotEntity.DB;
using NewLife.Reflection;
using WeiCloud.Utils;
using static QRCoder.PayloadGenerator;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using Pipelines.Sockets.Unofficial.Arenas;
using System.Threading;
using Microsoft.EntityFrameworkCore;
using NewLife.IP;
using WeiCloud.Utils.Common;
using WeiCloud.Utils.EncodeTools;
namespace ParkLotInfoService
{
@ -39,11 +27,14 @@ namespace ParkLotInfoService
private readonly IDictionaryService _dictionaryService;
private readonly IConfiguration _configuration;
private readonly string liFangkey = "cmVmb3JtZXJyZWZvcm1lcg==";
private JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
private readonly IHttpClientFactory _httpClientFactory;
public ParkingLotDataService(ILogger<ParkingLotDataService> logger, WeiCloudFusionContext context, IConfiguration configuration, IHttpClientFactory httpClientFactory, WeiCloudDbAxyjptContext dBContext, IDictionaryService dictionaryService)
{
_logger = logger;
@ -53,7 +44,9 @@ namespace ParkLotInfoService
_dBContext = dBContext;
_dictionaryService = dictionaryService;
}
#region 停车场
/// <summary>
/// 上传停车场信息
/// </summary>
@ -63,7 +56,7 @@ namespace ParkLotInfoService
{
ApiResult<int> result = new ApiResult<int>() { Code = RequestBackStatuEnum.success.Value, Msg = "接口请求成功" };
//ParkingAccessRecordDto dto=new ParkingAccessRecordDto();
long projectId = 0;
long projectId = 0;
try
{
var projectIdStr = _configuration["PorjectId"];
@ -90,8 +83,8 @@ namespace ParkLotInfoService
_logger.LogError(ex, $"PostParkingLots 上传停车场信息失败:{ex.Message}");
}
return result;
}
/// <summary>
/// 获取停车场信息
/// </summary>
@ -123,7 +116,6 @@ namespace ParkLotInfoService
return result;
}
result.Data = model;
}
catch (Exception ex)
{
@ -133,6 +125,7 @@ namespace ParkLotInfoService
}
return result;
}
/// <summary>
/// 获取立方接口数据
/// </summary>
@ -141,7 +134,6 @@ namespace ParkLotInfoService
/// <returns></returns>
private async Task<string> GetLifangData(string apiName, object parmJson)
{
string resStr = string.Empty;
//立方,目前只能本地测试
var url = _configuration["ThirdApi:LifangParkLotApiAddress"] + apiName;
@ -157,33 +149,34 @@ namespace ParkLotInfoService
var content = new StringContent(json, Encoding.UTF8, "application/json");
//_ = Task.Run(async () =>
//{
try
{
var httpResponse = client.PostAsync(url, content);
var response = await httpResponse;
if (response.IsSuccessStatusCode)
{
resStr = await response.Content.ReadAsStringAsync();
}
// 处理响应...
}
catch (TaskCanceledException)
{
_logger.LogError(this.GetType().FullName + " PostSearchResult", string.Format("抛出了异常信息: 请求超时,但主进程不受影响;"));
//Console.WriteLine("请求超时,但主进程不受影响");
}
catch (Exception ex)
try
{
var httpResponse = client.PostAsync(url, content);
var response = await httpResponse;
if (response.IsSuccessStatusCode)
{
_logger.LogError(this.GetType().FullName + " PostSearchResult", string.Format("抛出了异常信息: 请求超时,请求失败;{0}", ex.Message));
resStr = await response.Content.ReadAsStringAsync();
}
// });
// 处理响应...
}
catch (TaskCanceledException)
{
_logger.LogError(this.GetType().FullName + " PostSearchResult", string.Format("抛出了异常信息: 请求超时,但主进程不受影响;"));
//Console.WriteLine("请求超时,但主进程不受影响");
}
catch (Exception ex)
{
_logger.LogError(this.GetType().FullName + " PostSearchResult", string.Format("抛出了异常信息: 请求超时,请求失败;{0}", ex.Message));
}
// });
return resStr;
}
public async Task<ApiResult<string>> GetIpPing()
{
ApiResult<string> result = new ApiResult<string>() { Code = RequestBackStatuEnum.success.Value, Msg = "接口请求成功!" };
int timeout = 1000; // 超时时间(毫秒)
int timeout = 1000; // 超时时间(毫秒)
try
{
//立方停车场摄像头
@ -196,9 +189,9 @@ namespace ParkLotInfoService
}
var ptIpsLabel = ips.Select(d => new { Ip = d, LabelCode = "太阳宫车场识别仪Ip_" + d }).ToList();
//识别仪ip所在的识别仪设备
var pthings =await _dBContext.PtThingMapLabels.Where(a => ptIpsLabel.Select(b => b.LabelCode).Contains(a.LabelCode)).ToListAsync();
var pthings = await _dBContext.PtThingMapLabels.Where(a => ptIpsLabel.Select(b => b.LabelCode).Contains(a.LabelCode)).ToListAsync();
//所有识别仪状态点位
var statePtthings =await _dBContext.PtThings.Where(a => pthings.Select(b => b.ThingId).Contains(a.ParentId) && a.ParamCode == "AX_ChannelState").ToListAsync();
var statePtthings = await _dBContext.PtThings.Where(a => pthings.Select(b => b.ThingId).Contains(a.ParentId) && a.ParamCode == "AX_ChannelState").ToListAsync();
foreach (var item in ptIpsLabel)
{
//识别仪状态 0关闭 1开启
@ -221,7 +214,6 @@ namespace ParkLotInfoService
state = 1;
//Console.WriteLine($"来自 {reply.Address} 的回复: 字节={reply.Buffer.Length} 时间={reply.RoundtripTime}ms TTL={reply.Options?.Ttl ?? 0}");
}
}
//redis中更新识别仪状态
RealDataOnlyValueBo real = new RealDataOnlyValueBo() { Id = stateId.GetValueOrDefault(), Realvalue = state.ToString(), Updatetime = DateTime.Now };
@ -240,8 +232,11 @@ namespace ParkLotInfoService
}
return result;
}
#endregion
#endregion 停车场
#region 门禁
/// <summary>
/// 提交门禁状态记录
/// </summary>
@ -254,16 +249,16 @@ namespace ParkLotInfoService
try
{
//项目id
string proStr = _configuration["PorjectId"];
string proStr = _configuration["PorjectId"];
if (!string.IsNullOrEmpty(proStr))
{
projectId = long.Parse(proStr);
}
DoorStateRecord door = new DoorStateRecord() { Id = UidGenerator.Uid(),DoorId = dto.doorId, State =(short) dto.typeId, StateTime =DateTime.Parse(dto.date) , DoorName = dto.doorName, StateDesc = dto.typeName,CreateTime = DateTime.Now , ProjectId = projectId };
DoorStateRecord door = new DoorStateRecord() { Id = UidGenerator.Uid(), DoorId = dto.doorId, State = (short)dto.typeId, StateTime = DateTime.Parse(dto.date), DoorName = dto.doorName, StateDesc = dto.typeName, CreateTime = DateTime.Now, ProjectId = projectId };
_context.DoorStateRecords.Add(door);
_logger.LogError(this.GetType().FullName + " PostDoorControlRecord 入库前", string.Format("入库请求;{0}",_context.DoorStateRecords.Count()));
var res= await _context.SaveChangesAsync();
_logger.LogError(this.GetType().FullName + " PostDoorControlRecord 入库前", string.Format("入库请求;{0}", _context.DoorStateRecords.Count()));
var res = await _context.SaveChangesAsync();
if (res > 0)
{
_logger.LogError(this.GetType().FullName + " PostDoorControlRecord 入库后", string.Format("入库成功息: 请求超时,请求失败;{0}", door.Id));
@ -272,7 +267,7 @@ namespace ParkLotInfoService
result.Suc = 200;
}
else
{
{
result.Ret = "FAIL";
result.Suc = 2005;
}
@ -282,8 +277,8 @@ namespace ParkLotInfoService
_logger.LogError(this.GetType().FullName + " PostDoorControlRecord 保存记录--", string.Format("抛出了异常信息: 请求超时,请求失败;{0}", ex.Message));
}
return result;
}
/// <summary>
/// 门禁设备状态
/// </summary>
@ -303,30 +298,30 @@ namespace ParkLotInfoService
}
//门禁的设备状态写入redis
//找出所有的门禁设备
var data=await _dBContext.PtThings.ToListAsync();
var eqPthings=await _dBContext.PtThings.Where(a => a.ParamCode == "AccessControl").Select(d=>d.Id).ToListAsync();
var data = await _dBContext.PtThings.ToListAsync();
var eqPthings = await _dBContext.PtThings.Where(a => a.ParamCode == "AccessControl").Select(d => d.Id).ToListAsync();
if (eqPthings == null || eqPthings.Count == 0)
{ return result; }
var doorlocks =await _dBContext.PtThingMapLabels.Where(m => eqPthings.Contains(m.ThingId)&& m.LabelCode.Contains("安消门禁Id_")).Select(d=> new { Id = d.ThingId, DeciveId = int.Parse(d.LabelCode.Substring(d.LabelCode.LastIndexOf("_") + 1)) }).ToListAsync();
var doorlocks = await _dBContext.PtThingMapLabels.Where(m => eqPthings.Contains(m.ThingId) && m.LabelCode.Contains("安消门禁Id_")).Select(d => new { Id = d.ThingId, DeciveId = int.Parse(d.LabelCode.Substring(d.LabelCode.LastIndexOf("_") + 1)) }).ToListAsync();
if (doorlocks == null || doorlocks.Count == 0)
{
{
return result;
}
if (doorlocks == null || doorlocks.Count == 0)
{
{
return result;
}
//找出当前订阅推送的门禁id对应的设备
var doorLock=doorlocks.Where(a => a.DeciveId == dto.deviceld).FirstOrDefault();
var doorLock = doorlocks.Where(a => a.DeciveId == dto.deviceld).FirstOrDefault();
if (doorLock == null)
{
return result;
}
//找出当前门禁的状态点位
var realId=_dBContext.PtThings.Where(a =>a.ParentId== doorLock.Id && a.ParamCode == "AX_AcessState").FirstOrDefault()?.Id;
if (realId==0)
var realId = _dBContext.PtThings.Where(a => a.ParentId == doorLock.Id && a.ParamCode == "AX_AcessState").FirstOrDefault()?.Id;
if (realId == 0)
{
return result;
}
@ -339,8 +334,8 @@ namespace ParkLotInfoService
_logger.LogError(this.GetType().FullName + " PostDoorControlRecord", string.Format("抛出了异常信息: 请求超时,请求失败;{0}", ex.Message));
}
return result;
}
/// <summary>
/// 门禁远程控制
/// </summary>
@ -354,8 +349,8 @@ namespace ParkLotInfoService
string api = $"custom/v1/sendCommand?doorId={doorId}&command={command}";
try
{
string token =await GetLifangDoorLockToken();
var str = await GetLifangDoorLockPostData(api, null,token);
string token = await GetLifangDoorLockToken();
var str = await GetLifangDoorLockPostData(api, null, token);
if (string.IsNullOrEmpty(str))
{
result.Code = RequestBackStatuEnum.diy.Value;
@ -409,7 +404,7 @@ namespace ParkLotInfoService
//var client = _httpClientFactory.CreateClient();
client.Timeout = TimeSpan.FromMinutes(1);//设置超时时间
client.Timeout = TimeSpan.FromMinutes(1);//设置超时时间
try
{
var response = await client.GetAsync(apiUrl);
@ -437,13 +432,14 @@ namespace ParkLotInfoService
}
return token;
}
/// <summary>
/// 门禁调用立方接口信息
/// </summary>
/// <param name="apiName"></param>
/// <param name="parmJson"></param>
/// <returns></returns>
private async Task<string> GetLifangDoorLockPostData(string apiName, object parmJson,string token)
private async Task<string> GetLifangDoorLockPostData(string apiName, object parmJson, string token)
{
string json = string.Empty;
////获取token
@ -499,18 +495,19 @@ namespace ParkLotInfoService
}
return resStr;
}
/// <summary>
/// 调用订阅接口
/// </summary>
/// <param name="tppic"></param>
/// <param name="address"></param>
/// <param name="obj"></param>
/// <returns></returns>
public async Task<ApiResult<TokenDto>> PushLifangDoorData(string tppic, string address,string token)
public async Task<ApiResult<TokenDto>> PushLifangDoorData(string tppic, string address, string token)
{
ApiResult <TokenDto> result = new ApiResult<TokenDto>() { Code=RequestBackStatuEnum.success.Value,Msg="接口请求成功!"};
TokenDto resDto = new TokenDto() { Ret= "SUCESS",Suc= 200 };
ApiResult<TokenDto> result = new ApiResult<TokenDto>() { Code = RequestBackStatuEnum.success.Value, Msg = "接口请求成功!" };
TokenDto resDto = new TokenDto() { Ret = "SUCESS", Suc = 200 };
int expire = 0;
try
{
@ -526,7 +523,7 @@ namespace ParkLotInfoService
return result;
}
PushDoorDto dto = new PushDoorDto() { uuid = uuid, expire = expire, address = address, topic = tppic };
var res = await GetLifangDoorLockPostData(api, dto,token);
var res = await GetLifangDoorLockPostData(api, dto, token);
if (string.IsNullOrEmpty(res))
{
result.Code = RequestBackStatuEnum.fail.Value;
@ -538,17 +535,17 @@ namespace ParkLotInfoService
{
result.Code = RequestBackStatuEnum.diy.Value;
result.Msg = "下空失败!";
}
result.Data = resModel;
}
catch (Exception ex)
{
_logger.LogError(this.GetType().FullName + " PushLifangDoorData ", string.Format("抛出了异常信息:{0}",ex));
_logger.LogError(this.GetType().FullName + " PushLifangDoorData ", string.Format("抛出了异常信息:{0}", ex));
}
return result;
return result;
}
//public async Task<ApiResult<TokenDto>> PushLifangDoorRecord(string tppic, string address)
//{
// try
@ -560,6 +557,7 @@ namespace ParkLotInfoService
// _logger.LogError(this.GetType().FullName + " PushLifangDoorRecord ", string.Format("抛出了异常信息:{0}", ex));
// }
//}
#endregion
#endregion 门禁
}
}
}

@ -0,0 +1,46 @@
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.AspNetCore.Mvc;
using ThirdPartyServices.DomainService.PuTianSuYuan;
namespace ThirdPartyServices.API.Controllers.PuTianSuYuan
{
/// <summary>
/// 用于太阳宫看板的设备设施态势-普天溯源公司接口
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class SunPalaceBoardFacilityController : ControllerBase
{
private readonly ILogger<SunPalaceBoardFacilityController> _logger;
private readonly ISunPalaceBoardFacilityService _sunPalaceBoardFacilityService;
public SunPalaceBoardFacilityController(ILogger<SunPalaceBoardFacilityController> logger, ISunPalaceBoardFacilityService sunPalaceBoardFacilityService)
{
_logger = logger;
_sunPalaceBoardFacilityService = sunPalaceBoardFacilityService;
}
/// <summary>
/// 资产仪表盘数据-智慧建筑的看板上使用
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("assetList")]
public async Task<List<AssetOverviewResDto>> GetAssetDashboardEchart(SecSituationQueryDto dto)
{
return await _sunPalaceBoardFacilityService.GetAssetDashboardEchart(dto);
}
/// <summary>
/// 资产类型-智慧建筑的看板上使用
/// </summary>
/// <returns></returns>
[HttpPost("assetType")]
public async Task<List<AssetTypeResDto>> GetAssetTypeEchart(SecSituationQueryDto dto)
{
return await _sunPalaceBoardFacilityService.GetAssetTypeEchart(dto);
}
}
}

@ -0,0 +1,35 @@
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.AspNetCore.Mvc;
using ThirdPartyServices.DomainService.ShenZhouShengAn;
namespace ThirdPartyServices.API.Controllers.ShenZhouShengAn
{
/// <summary>
/// 用于太阳宫看板的综合安全态势模块-神州晟安公司接口
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class SunPalaceBoardSafetyController : ControllerBase
{
private readonly ILogger<SunPalaceBoardSafetyController> _logger;
private readonly ISunPalaceBoardSafetyService _secSituationService;
public SunPalaceBoardSafetyController(ILogger<SunPalaceBoardSafetyController> logger, ISunPalaceBoardSafetyService secSituationService)
{
_logger = logger;
_secSituationService = secSituationService;
}
/// <summary>
/// 生产风险识别(盾安云数据)智慧建筑的看板上使用
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpGet("productionRisk")]
public async Task<DangerRiskAreaResDto> GetProductionRiskEchart()
{
return await _secSituationService.GetProductionRiskEchart();
}
}
}

@ -0,0 +1,17 @@
using AutoMapper;
namespace ThirdPartyServices.API.Infrastructure
{
/// <summary>
/// 配置AutoMapper
/// </summary>
public class AutoMapperProfile : Profile
{
/// <summary>
/// 构造函数
/// </summary>
public AutoMapperProfile()
{
}
}
}

@ -0,0 +1,31 @@
using Autofac;
using System.Reflection;
namespace ThirdPartyServices.API.Infrastructure
{
/// <summary>
/// autofac
/// </summary>
public class ConfigureAutofac : Autofac.Module
{
/// <summary>
///
/// </summary>
/// <param name="builder"></param>
protected override void Load(ContainerBuilder builder)
{
//Assembly assemblysServices1 = Assembly.Load("WeiCloud.Core");
//builder.RegisterAssemblyTypes(assemblysServices1).Where(t => t.Namespace != "" && t.Namespace != null && t.Name.EndsWith("Service") && t.Namespace.StartsWith("WeiCloud.Core"))
// .AsImplementedInterfaces()
// .InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
var assemblysServices = Assembly.Load("ThirdPartyServices.DomainService");
builder.RegisterAssemblyTypes(assemblysServices)
.Where(x => x.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
// builder.RegisterType(typeof(GrainFactory)).PropertiesAutowired().InstancePerLifetimeScope();
}
}
}

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwExceptions="false"
internalLogLevel="Warn" internalLogFile="nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!--<variable name="myvar" value="myvalue"/>-->
<variable name="year" value="${date:format=yyyy}"/>
<variable name="year_month" value="${date:format=yyyy-MM}"/>
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets async="true">
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<!--
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target xsi:type="AsyncWrapper" name="MyLogger">
<target xsi:type="File"
layout="${longdate},${uppercase:${level}},${message}"
fileName="${basedir}/Log/${level}/${year}/${year_month}/${shortdate}.log" encoding="utf-8" />
</target>
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
<!--跳过Microsoft的系统日志-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Debug" writeTo="MyLogger" final="true"/>
<logger name="Microsoft.*" minlevel="Warn" writeTo="MyLogger" final="true"/>
</rules>
</nlog>

@ -1,27 +1,128 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Common.Shared.Application.Core;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Extensions.Logging;
using NLog.Web;
using System.Reflection;
using ThirdPartyServices.API.Infrastructure;
namespace ThirdPartyServices.API
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main");
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();
builder.Services.AddControllers();
builder.Services.AddSingleton(builder.Configuration);
#region Cors
var isconfig = builder.Configuration.GetSection("IdentityClientConfig").Get<CorsWithOrigins>();
builder.Services.AddCors(options =>
{
options.AddPolicy("_myAllowSpecificOrigins",
builder =>
{
builder
//.WithOrigins(isconfig.CorsOrigins) //被允许的来源,多个使用逗号分隔
.AllowAnyOrigin() //允许所有源访问本API(开发环境设置)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((h) => true);//为Signalr新添加的配置
});
});
#endregion Cors
#region SwaggerUI
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1.0", new OpenApiInfo
{
Version = "v1.0",
Title = "WeiCloud.IoT",//左侧大标题名称
Description = "安消一体化平台",
Contact = new OpenApiContact
{
Name = "hi7t",
Email = "",
Url = null
}
});
//c.OperationFilter<AddProjectHeaderParameter>();
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath, true);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
#endregion SwaggerUI
builder.Services.AddLogging(m => { m.AddNLog(); });
#region Autofac
// Add services to the container.
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new ConfigureAutofac());
});
builder.Services.AddControllers();
#endregion Autofac
var app = builder.Build();
// 设置全局默认请求体大小限制
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 200 * 1024 * 1024; // 默认 200MB
});
// Configure the HTTP request pipeline.
var app = builder.Build();
app.UseHttpsRedirection();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "WeiCloud.IoT-v1.0");
});
}
app.UseAuthorization();
// app.UseHttpsRedirection();
// app.UseAuthorization();
app.MapControllers();
app.MapControllers();
app.MapGet("/healthz", () => Results.Ok("OK"));
app.Run();
// 创建 Startup 实例
var startup = new Startup(builder.Configuration);
startup.Configure(app, app.Environment, builder.Configuration);
app.Run();
}
catch (Exception exception)
{
// NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
}
}
}

@ -13,7 +13,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5053",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@ -23,7 +23,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7195;http://localhost:5053",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@ -32,10 +32,10 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}

@ -0,0 +1,19 @@
using WeiCloud.Utils.Common;
namespace ThirdPartyServices.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfiguration configuration)
{
ServiceLocator.Instance = app.ApplicationServices;
}
}
}

@ -4,12 +4,23 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Folder Include="Controllers\PuCe\" />
<Folder Include="Controllers\PuTianSuYuan\" />
<Folder Include="Controllers\ShenZhouShengAn\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ThirdPartyServices.Application\ThirdPartyServices.Application.csproj" />
<ProjectReference Include="..\ThirdPartyServices.DomainService\ThirdPartyServices.DomainService.csproj" />
<ProjectReference Include="..\ThirdPartyServices.Entity\ThirdPartyServices.Entity.csproj" />
</ItemGroup>
</Project>

@ -5,5 +5,17 @@
"Microsoft.AspNetCore": "Warning"
}
},
//
"ThirdParty": {
"AssetWeb": {
"ServiceUrl": "http://123.56.129.171:8280/services/AssetWeb.asmx",
"TimeoutSeconds": "30",
"MaxMsgSize": "10485760", // 10MB
"BasicAuthUser": "",
"BasicAuthPassword": "",
"TokenHeader": ""
},
"SzdunanCode": "123456"
},
"AllowedHosts": "*"
}
}

@ -0,0 +1,68 @@
using System.Text.Json;
using System.Text.Json.Serialization;
//盾安云第三方请求接口的参数
namespace ThirdPartyServices.Application.ShenZhouShengAn.RequestDto
{
/// <summary>
/// 用户信息参数
/// </summary>
public class LoginUsersConfiguration
{
[JsonPropertyName("uid")]
public int Uid { get; set; }
[JsonPropertyName("ubpid")]
public int Ubpid { get; set; }
[JsonPropertyName("id")]
public int UserId { get; set; }
}
/// <summary>
/// 单位风险点汇总数据
/// </summary>
public class RiskAreaQueryDto
{
/// <summary>
/// 单位id
/// </summary>
public int Branch_Id { get; set; } = 0;
/// <summary>
/// Ubpid
/// </summary>
public int Ubpid { get; set; } = 0;
/// <summary>
/// Uid
/// </summary>
public int Uid { get; set; } = 0;
}
/// <summary>
/// 条件组合查询隐患数据
/// </summary>
public class DangerInfoQueryDto
{
public int? Ubpid { get; set; }
/// <summary>
/// /隐患状态:0待核查,1待整改,2待验收,3治理完毕,4不是隐患
/// </summary>
public string Status { get; set; }
/// <summary>
/// 第三方定义的隐患等级2一般隐患,3重大隐患
/// </summary>
public string? Result { get; set; }
public int? Page { get; set; }
public int? Branch_id { get; set; }
public string? Start_time { get; set; }
public string? End_time { get; set; }
}
}

@ -0,0 +1,38 @@
//第三方返回数据
using System.Text.Json.Serialization;
namespace ThirdPartyServices.Application.ShenZhouShengAn.ResponseDto
{
/// <summary>
/// 返回token模型
/// </summary>
public class LoginTokenDto
{
public string? Token { get; set; }
}
/// <summary>
/// 用户单位信息参数
/// </summary>
public class BranchResDto
{
[JsonPropertyName("branch_permissions_ids")]
public int[] BranchPermissionIds { get; set; }
}
/// <summary>
/// 用于第三方请求的结果
/// </summary>
/// <typeparam name="T"></typeparam>
public class HttpClientResult<T>
{
[JsonPropertyName("code")]
public string Code { get; set; }
[JsonPropertyName("message")]
public string Message { get; set; }
[JsonPropertyName("data")]
public T Data { get; set; }
}
}

@ -9,7 +9,12 @@
<ItemGroup>
<Folder Include="PuCe\" />
<Folder Include="PuTianSuYuan\" />
<Folder Include="ShenZhouShengAn\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.ServiceModel.Http" Version="8.1.2" />
<PackageReference Include="System.ServiceModel.Primitives" Version="8.1.2" />
<PackageReference Include="System.Text.Json" Version="9.0.8" />
</ItemGroup>
</Project>

@ -0,0 +1,93 @@
using Microsoft.Extensions.Configuration;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml;
namespace ThirdPartyServices.DomainService.PuTianSuYuan
{
//生成代码命令(需安装 dotnet-svcutil 工具):
// dotnet-svcutil http://123.56.129.171:8280/services/AssetWeb.asmx?wsdl `
//--targetFramework net8.0 `
//--outputFile ServiceProxies\AssetWebClientService.cs `
//--namespace "*,ThirdPartyServices.DomainService.PuTianSuYuan" `
//--noTypeReuse `
//--serializer XmlSerializer
public sealed class AssetWebContextService : IAssetWebService
{
public StatisticsServiceClient Client { get; }
private readonly string? _tokenHeader;
private readonly IConfiguration _cfg;
public AssetWebContextService(IConfiguration configuration)
{
_cfg = configuration;
// ① 读取配置(全部字符串,按需转 int/TimeSpan)
var prefix = "ThirdParty:AssetWeb:";
var serviceUrl = _cfg[$"{prefix}ServiceUrl"]
?? throw new InvalidOperationException("ServiceUrl 缺失");
var timeoutSecStr = _cfg[$"{prefix}TimeoutSeconds"] ?? "30";
var maxMsgStr = _cfg[$"{prefix}MaxMsgSize"] ?? "10485760";
// ② 绑定
var binding = new BasicHttpBinding(
serviceUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase)
? BasicHttpSecurityMode.Transport
: BasicHttpSecurityMode.None)
{
MaxReceivedMessageSize = int.Parse(maxMsgStr),
ReaderQuotas = XmlDictionaryReaderQuotas.Max,
SendTimeout = TimeSpan.FromSeconds(int.Parse(timeoutSecStr)),
ReceiveTimeout = TimeSpan.FromSeconds(int.Parse(timeoutSecStr))
};
// ③ 端点 & 客户端
var endpoint = new EndpointAddress(serviceUrl);
Client = new StatisticsServiceClient(binding, endpoint);
// ④ BasicAuth(可无)
var user = _cfg[$"{prefix}BasicAuthUser"];
var pwd = _cfg[$"{prefix}BasicAuthPassword"];
if (!string.IsNullOrWhiteSpace(user) && !string.IsNullOrWhiteSpace(pwd))
{
Client.ClientCredentials.UserName.UserName = user;
Client.ClientCredentials.UserName.Password = pwd;
}
// ⑤ Token Header(可无)
_tokenHeader = _cfg[$"{prefix}TokenHeader"];
}
/// <summary>如需自定义 Token Header 调用,用此包装;否则直接调 Client 方法。</summary>
public async Task<TResp> WithTokenAsync<TResp>(Func<Task<TResp>> func)
{
if (string.IsNullOrEmpty(_tokenHeader))
return await func();
using var scope = new OperationContextScope(Client.InnerChannel);
var hdr = MessageHeader.CreateHeader(
"SessionToken",
"http://service.webservice.fits.ptsy.com/",
_tokenHeader);
OperationContext.Current!.OutgoingMessageHeaders.Add(hdr);
return await func();
}
public async ValueTask DisposeAsync()
{
try
{
if (Client.State == CommunicationState.Faulted)
Client.Abort();
else if (Client.State != CommunicationState.Closed)
Client.Close();
}
catch { Client.Abort(); }
await ValueTask.CompletedTask;
}
}
}

@ -0,0 +1,7 @@
namespace ThirdPartyServices.DomainService.PuTianSuYuan
{
public interface IAssetWebService : IAsyncDisposable
{
StatisticsServiceClient Client { get; }
}
}

@ -0,0 +1,12 @@
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
namespace ThirdPartyServices.DomainService.PuTianSuYuan
{
public interface ISunPalaceBoardFacilityService
{
Task<List<AssetOverviewResDto>> GetAssetDashboardEchart(SecSituationQueryDto dto);
Task<List<AssetTypeResDto>> GetAssetTypeEchart(SecSituationQueryDto dto);
}
}

@ -0,0 +1,196 @@
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.Extensions.Logging;
namespace ThirdPartyServices.DomainService.PuTianSuYuan
{
public class SunPalaceBoardFacilityService : ISunPalaceBoardFacilityService
{
private readonly ILogger<SunPalaceBoardFacilityService> _logger;
private readonly IAssetWebService _assetWebService;
public SunPalaceBoardFacilityService(ILogger<SunPalaceBoardFacilityService> logger, IAssetWebService assetWebService)
{
_logger = logger;
_assetWebService = assetWebService;
}
public async Task<List<AssetOverviewResDto>> GetAssetDashboardEchart(SecSituationQueryDto dto)
{
List<AssetOverviewResDto> result = [];
DateTime start = DateTime.Now;
DateTime end = DateTime.Now;
////时间范围
switch (dto.QueryTimeType)
{
case (int)QueryTimeEnum.Custom:
start = dto.StartTime.Value;
end = dto.EndTime.Value;
break;
case (int)QueryTimeEnum.Monthly:
// 本月从 1号 00:00 到现在
start = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
break;
default:
return result;
}
try
{
List<AssetOverviewResDto> resDtos = [];
//总资产数
var assetCount = await _assetWebService.Client.assetCountAsync(null, null);
AssetOverviewResDto assetOverviewRes = new()
{
TotalAssetCount = assetCount.@return,
OrderBy = 1,
Name = "总资产数",
TotalAssetCountGrowthRate = 5.2
};
resDtos.Add(assetOverviewRes);
//总资产价值
var assetTotalPrice = await _assetWebService.Client.assetTotalPriceAsync(null, null);
AssetOverviewResDto assetPriceRes = new AssetOverviewResDto
{
TotalAssetCount = assetTotalPrice.@return,
OrderBy = 2,
Name = "总资产价值",
TotalAssetCountGrowthRate = 0.052
};
resDtos.Add(assetPriceRes);
//资产盘点
AssetOverviewResDto assetReviewRes = new AssetOverviewResDto
{
TotalAssetCount = 0.92,
OrderBy = 3,
Name = "资产盘点",
};
resDtos.Add(assetReviewRes);
//资产分布
AssetOverviewResDto assetDistributeRes = new AssetOverviewResDto
{
TotalAssetCount = 6,
OrderBy = 4,
Name = "资产分布",
};
resDtos.Add(assetDistributeRes);
//在保资产
AssetOverviewResDto assetInRes = new AssetOverviewResDto
{
TotalAssetCount = 876,
OrderBy = 5,
Name = "在保资产",
TotalAssetCountGrowthRate = 0.021
};
resDtos.Add(assetInRes);
//待维修资产
var awaitRepair = await _assetWebService.Client.assetAwaitRepairAsync();
AssetOverviewResDto assetRepairRes = new AssetOverviewResDto
{
TotalAssetCount = awaitRepair.@return != null ? awaitRepair.@return.Length : 0,
OrderBy = 6,
Name = "待维修资产",
TotalAssetCountGrowthRate = 0.083
};
resDtos.Add(assetRepairRes);
//本月折旧
AssetOverviewResDto assetDepreciationRes = new AssetOverviewResDto
{
TotalAssetCount = 245678.5,
OrderBy = 7,
Name = "本月折旧",
TotalAssetCountGrowthRate = 0.035
};
resDtos.Add(assetDepreciationRes);
//今日报警
var todayAlarm = await _assetWebService.Client.todayAlarmAsync();
AssetOverviewResDto assetAlarmRes = new AssetOverviewResDto
{
TotalAssetCount = todayAlarm.@return,
OrderBy = 8,
Name = "今日报警",
};
resDtos.Add(assetAlarmRes);
result = resDtos;
return result;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "GetAssetDashboardEchart接口出错");
}
return result;
}
/// <summary>
/// 资产类型图
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<List<AssetTypeResDto>> GetAssetTypeEchart(SecSituationQueryDto dto)
{
List<AssetTypeResDto> result = [];
DateTime start = DateTime.Now;
DateTime end = DateTime.Now;
////时间范围
switch (dto.QueryTimeType)
{
case (int)QueryTimeEnum.Custom:
start = dto.StartTime.Value;
end = dto.EndTime.Value;
break;
case (int)QueryTimeEnum.Monthly:
// 本月从 1号 00:00 到现在
start = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
break;
default:
return result;
}
try
{
List<AssetTypeResDto> assetTypes = [];
var assetType = await _assetWebService.Client.assetTypeStatisticsAsync("", "");
if (assetType?.@return != null && assetType.@return.Length > 0)
{
foreach (var item in assetType.@return)
{
assetTypes.Add(new AssetTypeResDto
{
AssetType = item.name,
AssetCount = item.count,
});
}
}
result = assetTypes;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "GetAssetTypeEchart接口出错");
}
return result;
}
}
}

@ -0,0 +1,16 @@
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
namespace ThirdPartyServices.DomainService.ShenZhouShengAn
{
public interface ISunPalaceBoardSafetyService
{
//Task<ApiResult<List<SecurityHiddenDangerHighRiskAreaResDto>>> GetHiddenDangerTrend(SecSituationQueryDto dto);
//Task<ApiResult<List<IdCardAlarmResDto>>> GetIdCardAlarmEchart();
Task<DangerRiskAreaResDto> GetProductionRiskEchart();
//Task<ApiResult<AlarmInfoResultPageModelV02>> GetUnAlarmInfoList(AlarmEventEchartQueryDto dto);
}
}

@ -0,0 +1,39 @@
//盾安云第三方请求接口
using ThirdPartyServices.Application.ShenZhouShengAn.RequestDto;
using ThirdPartyServices.Application.ShenZhouShengAn.ResponseDto;
namespace ThirdPartyServices.DomainService.ShenZhouShengAn
{
/// <summary>
/// 获取第三方登录的Token服务接口
/// </summary>
public interface IThirdPartyProviderService
{
/// <summary>
/// 获取token,
/// </summary>
/// <param name="userCode"></param>
/// <returns></returns>
Task<string?> GetTokenAsync(string userCode);
Task<HttpClientResult<LoginUsersConfiguration>> GetUserConfiguration(string token);
Task<HttpClientResult<BranchResDto>> GetBranchPermissions(string token, int ubpid);
/// <summary>
/// 请求第三方接口
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <param name="url"></param>
/// <param name="token"></param>
/// <param name="payload"></param>
/// <returns></returns>
Task<TResponse> SendAndParseAsync<TRequest, TResponse>(string url, string? token, TRequest payload,
HttpMethod method);
Task<string> SendJsonAsync<TRequest>(string url, string? token, TRequest payload,
HttpMethod method);
Task<TResponse?> SendAndParseAsync<TResponse>(string url, string? token, HttpMethod method);
}
}

@ -0,0 +1,127 @@
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ThirdPartyServices.Application.ShenZhouShengAn.RequestDto;
using ThirdPartyServices.Application.ShenZhouShengAn.ResponseDto;
namespace ThirdPartyServices.DomainService.ShenZhouShengAn
{
public class SunPalaceBoardSafetyService : ISunPalaceBoardSafetyService
{
private readonly IThirdPartyProviderService _tokenProviderService;
private readonly ILogger<SunPalaceBoardSafetyService> _logger;
private readonly IConfiguration _configuration;
public SunPalaceBoardSafetyService(IThirdPartyProviderService thirdPartyProviderService, ILogger<SunPalaceBoardSafetyService> logger, IConfiguration configuration)
{
_tokenProviderService = thirdPartyProviderService;
_logger = logger;
_configuration = configuration;
}
/// <summary>
/// 生产风险识别(盾安云数据)-智慧建筑的看板上使用
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<DangerRiskAreaResDto> GetProductionRiskEchart()
{
var result = new DangerRiskAreaResDto()
{
DangerInfos = new List<DangerInfo>(),
ProductionRiskStats = new List<ProductionRiskStatsResDto>()
};
try
{
//获取token
var token = await _tokenProviderService.GetTokenAsync(_configuration["ThirdParty:SzdunanCode"]!);
if (string.IsNullOrWhiteSpace(token))
{
_logger.LogWarning("GetProductionRiskEchart接口获取token失败");
return result;
}
//获取用户配置
HttpClientResult<LoginUsersConfiguration> loginUsers = await _tokenProviderService.GetUserConfiguration(token);
if (loginUsers.Code == "Error")
{
_logger.LogWarning("GetProductionRiskEchart接口获取用户配置失败");
return result;
}
//获取单位信息
HttpClientResult<BranchResDto> branchs = await _tokenProviderService.GetBranchPermissions(token, loginUsers.Data.Uid);
if (branchs.Code == "Error")
{
_logger.LogWarning("GetProductionRiskEchart接口获取单位信息失败");
return result;
}
//生产风险识别
HttpClientResult<DangerRiskAreaResDto> riskResult = await _tokenProviderService.SendAndParseAsync<RiskAreaQueryDto, HttpClientResult<DangerRiskAreaResDto>>(
"https://zrh.szdunan.cn/v1/api/home/risk/index", token,
new RiskAreaQueryDto
{
Branch_Id = branchs.Data.BranchPermissionIds[0],
Ubpid = loginUsers.Data.Ubpid,
Uid = loginUsers.Data.Uid
}, HttpMethod.Post);
result.ProductionRiskStats = riskResult.Data.ProductionRiskStats;
//获取隐患信息
string[] dangerStatus = ["0", "1", "2",]; //0-待核查,1-待整改,2-待验收
int[] dangerLevel = [3]; //2一般隐患,3重大隐患。目前只要重大隐患,如果要查询一般隐患,可以将2添加到数组中
List<DangerInfo> dangerInfoList = [];
DangerInfo dangerInfo = new DangerInfo();
var tasks = new List<Task<DangerInfo>>();
foreach (string status in dangerStatus)
{
tasks.Add(Task.Run(async () =>
{
var info = new DangerInfo { Status = status };
// 1. 查该状态下的总数
string jsonResult = await _tokenProviderService.SendJsonAsync<DangerInfoQueryDto>("https://zrh.szdunan.cn/v1/api/danger/ledger/dangerInfo/new", token, new DangerInfoQueryDto { Ubpid = loginUsers.Data.Ubpid, Status = status }, HttpMethod.Post);
var jObj = JObject.Parse(jsonResult);
int total = jObj["data"]?["total"]?.Value<int>() ?? 0;
info.StatusCount = total;
//// 2. 查该状态 + 等级下的总数(只要一个等级的话可以直接取)
//jsonResult = await _tokenProviderService.SendJsonAsync<DangerInfoQueryDto>("https://zrh.szdunan.cn/v1/api/danger/ledger/dangerInfo/new", token, new DangerInfoQueryDto { Ubpid = loginUsers.Data.Ubpid, Status = status, Result = "3" }, HttpMethod.Post);
//jObj = JObject.Parse(jsonResult);
//int levelTotal = jObj["data"]?["total"]?.Value<int>() ?? 0;
//info.DangerLevelCount = levelTotal;
return info;
}));
}
dangerInfoList = [.. (await Task.WhenAll(tasks))];
//3.待排查
DateTime startTime = new DateTime(DateTime.Today.Year, 1, 1);
dangerInfo = new DangerInfo();
var jsonBranch = await _tokenProviderService.SendJsonAsync("https://zrh.szdunan.cn/v1/api/danger/task/index_branch", token, new DangerInfoQueryDto { Status = "0", Branch_id = branchs.Data.BranchPermissionIds[0], Start_time = startTime.ToString("yyyy-MM-dd HH:mm:ss"), End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }, HttpMethod.Post);
var jObj = JObject.Parse(jsonBranch);
int total = jObj["data"]?["total"]?.Value<int>() ?? 0;
dangerInfo.StatusCount = total;
dangerInfo.Status = "3"; //待排查
dangerInfoList.Add(dangerInfo);
result.DangerInfos = dangerInfoList;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "GetProductionRiskEchart接口出错");
}
return result;
}
}
}

@ -0,0 +1,170 @@
using Microsoft.Extensions.Logging;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using ThirdPartyServices.Application.ShenZhouShengAn.RequestDto;
using ThirdPartyServices.Application.ShenZhouShengAn.ResponseDto;
namespace ThirdPartyServices.DomainService.ShenZhouShengAn
{
/// <summary>
/// 盾安云服务
/// </summary>
public class ThirdPartyProviderService : IThirdPartyProviderService
{
// private readonly HttpClient _httpClient;
private readonly ILogger<ThirdPartyProviderService> _logger;
private static string? _cachedToken;
private static DateTime _tokenExpiry = DateTime.MinValue;
public ThirdPartyProviderService(HttpClient httpClient, ILogger<ThirdPartyProviderService> logger)
{
// _httpClient = httpClient;
_logger = logger;
}
/// <summary>
/// 开发测试的时候,忽略证书
/// </summary>
private static readonly HttpClient _httpClient = new(new HttpClientHandler
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
});
/// <summary>
/// 获取登录tonken
/// </summary>
/// <param name="userCode"></param>
/// <returns></returns>
public async Task<string?> GetTokenAsync(string userCode)
{
if (!string.IsNullOrEmpty(_cachedToken) && _tokenExpiry > DateTime.Now)
return _cachedToken;
try
{
var loginRes = await _httpClient.PostAsJsonAsync("https://zrh.szdunan.cn/v1/api/zrh/login", new { code = userCode });
if (!loginRes.IsSuccessStatusCode) return null;
var loginData = await loginRes.Content.ReadFromJsonAsync<HttpClientResult<LoginTokenDto>>();
if (loginData?.Code != "Success") return null;
_cachedToken = loginData.Data.Token;
_tokenExpiry = DateTime.Now.AddMinutes(55); // 假设 token 有效期 1 小时,提前5分钟过期
return _cachedToken;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取盾安云 token 失败");
return null;
}
}
/// <summary>
/// 获取用户配置
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public async Task<HttpClientResult<LoginUsersConfiguration>> GetUserConfiguration(string token)
{
HttpClientResult<LoginUsersConfiguration> result = new HttpClientResult<LoginUsersConfiguration>() { Code = "Success", Message = "请求成功" };
result = await SendAndParseAsync<HttpClientResult<LoginUsersConfiguration>>(
"https://zrh.szdunan.cn/v1/api/users",
token,
HttpMethod.Post);
return result;
}
/// <summary>
/// 获取用户单位信息参数
/// </summary>
/// <param name="token"></param>
/// <param name="ubpid"></param>
/// <returns></returns>
public async Task<HttpClientResult<BranchResDto>> GetBranchPermissions(string token, int ubpid)
{
HttpClientResult<BranchResDto> result = new HttpClientResult<BranchResDto>() { Code = "Success", Message = "请求成功" };
result = await SendAndParseAsync<int, HttpClientResult<BranchResDto>>(
"https://zrh.szdunan.cn/v1/api/branch/index_no_check_branch",
token,
ubpid,
HttpMethod.Post);
return result;
}
/// <summary>
/// 请求第三方API,发送JSON数据,不支持get和delete方法
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <param name="url"></param>
/// <param name="token"></param>
/// <param name="payload"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<string> SendJsonAsync<TRequest>(string url, string? token, TRequest? payload, HttpMethod method)
{
using var request = new HttpRequestMessage(method, url);
if (!string.IsNullOrWhiteSpace(token))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
// 写入 JSON 请求体(POST、PUT、PATCH 等适用)
if (payload != null && method != HttpMethod.Get)
{
request.Content = JsonContent.Create(payload); // 使用 System.Net.Http.Json
}
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
throw new Exception($"请求失败:{response.StatusCode}, 内容:{error}");
}
return await response.Content.ReadAsStringAsync();
}
/// <summary>
/// 返回强类型
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TResponse"></typeparam>
/// <param name="url"></param>
/// <param name="token"></param>
/// <param name="payload"></param>
/// <returns></returns>
public async Task<TResponse> SendAndParseAsync<TRequest, TResponse>(
string url,
string? token,
TRequest? payload,
HttpMethod method)
{
var json = await SendJsonAsync(url, token, payload, method);
return JsonSerializer.Deserialize<TResponse>(json);
}
/// <summary>
/// 重载
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="url"></param>
/// <param name="token"></param>
/// <param name="method"></param>
/// <returns></returns>
public Task<TResponse?> SendAndParseAsync<TResponse>(
string url,
string? token,
HttpMethod method)
{
return SendAndParseAsync<object, TResponse>(url, token, null, method);
}
}
}

@ -8,8 +8,16 @@
<ItemGroup>
<Folder Include="PuCe\" />
<Folder Include="PuTianSuYuan\" />
<Folder Include="ShenZhouShengAn\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="6.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Common.SharedService\Common.Shared.Application\Common.Shared.Application.csproj" />
<ProjectReference Include="..\..\WeiCloud.Core\WeiCloud.Core.csproj" />
<ProjectReference Include="..\ThirdPartyServices.Application\ThirdPartyServices.Application.csproj" />
</ItemGroup>
</Project>

@ -2,7 +2,6 @@
using Common.Shared.DomainService;
using Microsoft.AspNetCore.Mvc;
using Video.DomainService;
using WeiCloud.Core.BaseModels;
namespace Video.API.Controllers.DaHua
{

@ -1,5 +1,5 @@
using Common.Shared.Application.DaHua;
using WeiCloud.Core.BaseModels;
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.DaHua;
namespace Video.DomainService
{

@ -1,7 +1,7 @@
using Common.Shared.Application.DaHua;
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.DaHua;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using WeiCloud.Core.BaseModels;
namespace Video.DomainService
{

Loading…
Cancel
Save