dev_lx #41

Merged
LiuXin merged 2 commits from dev_lx into main 3 weeks ago
  1. 2
      WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/AppHost.cs
  2. 1
      WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/Manage.AppHost.AppHost.csproj
  3. 5
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/Common.Shared.Application.csproj
  4. 58
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/SafetyFirePro/RequestDto/RdsUserInfoManagerReqDto.cs
  5. 51
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/SafetyFirePro/ResponseDto/RdsUserInfoManagerResDto.cs
  6. 11
      WeiCloud.Fusion/ReadME.md
  7. 47
      WeiCloud.Fusion/UCPlatform.Entities/Model/RdsSafetyUser.cs
  8. 9
      WeiCloud.Fusion/UCPlatform.Entities/UCPlatform.Entities.csproj
  9. 2
      WeiCloud.Fusion/UC_PlatformServices/ReadME.md
  10. 58
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Controllers/UC_PlatformController.cs
  11. 17
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Infrastructure/AutoMapperProfile.cs
  12. 34
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Infrastructure/ConfigureAutofac.cs
  13. 57
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/NLog.config
  14. 145
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Program.cs
  15. 52
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Properties/launchSettings.json
  16. 20
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/Startup.cs
  17. 23
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/UCPlatform.API.csproj
  18. 6
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/UCPlatform.API.http
  19. 12
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/WeatherForecast.cs
  20. 12
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.API/appsettings.json
  21. 32
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.Application/IdentityClientConfig.cs
  22. 9
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.Application/UCPlatform.Application.csproj
  23. 9
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.Domain/UCPlatform.Domain.csproj
  24. 19
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.DomainService/IRdsUserInfoManagerService.cs
  25. 282
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.DomainService/RdsUserInfoManagerService.cs
  26. 16
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.DomainService/UCPlatform.DomainService.csproj
  27. 73
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.Store/FusionDbContext.cs
  28. 18
      WeiCloud.Fusion/UC_PlatformServices/UCPlatform.Store/UCPlatform.Store.csproj
  29. 4
      WeiCloud.Fusion/VideoService/Video.API/Program.cs
  30. 5
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs
  31. 18
      WeiCloud.Fusion/WeiCloud.Core/Extension/FriendlyException.cs
  32. 83
      WeiCloud.Fusion/WeiCloud.Core/Extension/IQueryableExtensions.cs
  33. 198
      WeiCloud.Fusion/WeiCloud.Core/Extension/TryConvertExtension.cs
  34. 48
      WeiCloud.Fusion/WeiCloud.Fusion.sln

@ -6,11 +6,13 @@ 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");
var ucplatform = builder.AddProject<Projects.UCPlatform_API>("ucplatformapi");
builder.AddProject<Projects.Manage_AppHost_Web>("webfrontend")
.WithReference(videoapi)
.WithReference(alarmapi)
.WithReference(thirdpartyapi)
.WithReference(ucplatform)
.WithExternalHttpEndpoints()
.WithHttpHealthCheck("/health")
.WithReference(apiService)

@ -14,6 +14,7 @@
<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="..\..\UC_PlatformServices\UCPlatform.API\UCPlatform.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" />

@ -7,7 +7,7 @@
</PropertyGroup>
<PropertyGroup>
<PackageId>Common.Shared.Application</PackageId>
<Version>4.3</Version>
<Version>5.1</Version>
<Authors>zrh-lx</Authors>
<Company>zrh-lx</Company> <!-- 可选 -->
<Description>包含所有公共使用的 DTO、契约、接口模型等,供微服务之间共享使用</Description>
@ -16,4 +16,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn> <!-- 可选:忽略未注释警告 -->
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\WeiCloud.Utils\WeiCloud.Utils.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,58 @@
using WeiCloud.Utils.Common;
namespace Common.Shared.Application.SafetyFirePro.RequestDto
{
public class AddorEditRdsUserReqDto
{
/// <summary>
/// 主键
/// 为空的时候就是新增
/// 有id就是编辑
/// </summary>
public long? Id { get; set; }
/// <summary>
/// 安消用户id
/// </summary>
public long SafetyUserId { get; set; }
/// <summary>
/// 融合通信调度用户
/// </summary>
public string RdsUserId { get; set; } = null!;
/// <summary>
/// 融合通信用户类型0:其他
/// 1:调度台
/// 2:调度用户
/// 3:SIP用户
/// 4:集群网关用户
/// 5:外部用户
/// </summary>
public int RdsUserType { get; set; }
/// <summary>
/// 融合通信中用户手机号,唯一不可重复纯数字
/// </summary>
public string RdsUserPhorex { get; set; } = null!;
/// <summary>
/// 融合通信用户名
/// </summary>
public string RdsUserName { get; set; } = null!;
/// <summary>
/// 融合通信账号
/// </summary>
public string RdsUserAccount { get; set; } = null!;
}
/// <summary>
/// 用在查询和删除上,不一定传递哪个参数,所以做成通用
/// </summary>
public class RdsUserReqDto
{
public long? SafetyUserId { get; set; }
public string? RdsUserId { get; set; }
}
}

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common.Shared.Application.SafetyFirePro.ResponseDto
{
public class RdsUserInfoResDto
{
/// <summary>
/// 主键
/// </summary>
public long Id { get; set; }
/// <summary>
/// 安消用户id
/// </summary>
public long SafetyUserId { get; set; }
/// <summary>
/// 融合通信调度用户
/// </summary>
public string RdsUserId { get; set; } = null!;
/// <summary>
/// 融合通信用户类型0:其他
/// 1:调度台
/// 2:调度用户
/// 3:SIP用户
/// 4:集群网关用户
/// 5:外部用户
/// </summary>
public int RdsUserType { get; set; }
/// <summary>
/// 融合通信中用户手机号,唯一不可重复纯数字
/// </summary>
public string RdsUserPhorex { get; set; } = null!;
/// <summary>
/// 融合通信用户名
/// </summary>
public string RdsUserName { get; set; } = null!;
/// <summary>
/// 融合通信账号
/// </summary>
public string RdsUserAccount { get; set; } = null!;
}
}

@ -1,2 +1,9 @@
# 融合通信模块
1. 目前嵌入到是青鸾公司融合通信模块
# 代码分层说明
1. 网关层 Ocelot:轻量,配置简单,统一入口;
2. WeiCloud.Utils工具层 WeiCloud.Utils:利用现有的V4的工具层;
3. Aspire微服务统一发现层(可选) Aspire:利用微软提供的Aspire做微服务的统一发编排,简单;
4. DDD的Entities实体层 包含该微服务的枚举、实体、领域模型等;
5. Web API 层 对外调用的控制器层;
6. DomainService服务层定义服务接口和服务实现类;
7. Dto的Domain层(可选) 定义涉及到的dto,可以通过AutoMapper做映射,也可以不用,可选;
8. Store数据库管理层. 三方数据一般都需要做保存到数据库,这个数据库是一个独立的新的库

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
namespace UCPlatform.Entities.Model;
public partial class RdsSafetyUser
{
/// <summary>
/// 主键
/// </summary>
public long Id { get; set; }
/// <summary>
/// 安消用户id
/// </summary>
public long SafetyUserId { get; set; }
/// <summary>
/// 融合通信调度用户
/// </summary>
public string RdsUserId { get; set; } = null!;
/// <summary>
/// 融合通信用户类型0:其他
/// 1:调度台
/// 2:调度用户
/// 3:SIP用户
/// 4:集群网关用户
/// 5:外部用户
/// </summary>
public int RdsUserType { get; set; }
/// <summary>
/// 融合通信中用户手机号,唯一不可重复纯数字
/// </summary>
public string RdsUserPhorex { get; set; } = null!;
/// <summary>
/// 融合通信用户名
/// </summary>
public string RdsUserName { get; set; } = null!;
/// <summary>
/// 融合通信账号
/// </summary>
public string RdsUserAccount { get; set; } = null!;
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,2 @@
# 融合通信模块
1. 目前嵌入到是青鸾公司融合通信模块

@ -0,0 +1,58 @@
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.AspNetCore.Mvc;
using UCPlatform.DomainService;
namespace UCPlatform.API.Controllers
{
/// <summary>
/// 控制器层
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class UC_PlatformController : ControllerBase
{
private readonly ILogger<UC_PlatformController> _logger;
private readonly IRdsUserInfoManagerService _rdsUserInfoManagerService;
public UC_PlatformController(ILogger<UC_PlatformController> logger, IRdsUserInfoManagerService rdsUserInfoManagerService)
{
_logger = logger;
_rdsUserInfoManagerService = rdsUserInfoManagerService;
}
/// <summary>
/// 新增或编辑
/// </summary>
/// <param name="reqDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<bool>> AddorEditRdsUserAsync(AddorEditRdsUserReqDto reqDto)
{
return await _rdsUserInfoManagerService.AddorEditRdsUserAsync(reqDto);
}
/// <summary>
/// 查询
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<List<RdsUserInfoResDto>>> GetRdsUserInfo([FromQuery] RdsUserReqDto dto)
{
return await _rdsUserInfoManagerService.GetRdsUserInfo(dto);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpDelete]
public async Task<ApiResult<bool>> DeleteRdsUserAsync([FromQuery] RdsUserReqDto dto)
{
return await _rdsUserInfoManagerService.DeleteRdsUserAsync(dto);
}
}
}

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

@ -0,0 +1,34 @@
using Autofac;
using System.Reflection;
using WeiCloud.Utils;
namespace UCPlatform.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("UCPlatform.DomainService");
builder.RegisterAssemblyTypes(assemblysServices)
.Where(x => x.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
// builder.RegisterType(typeof(GrainFactory)).PropertiesAutowired().InstancePerLifetimeScope();
builder.RegisterType<DictionaryService>().As<IDictionaryService>();
}
}
}

@ -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>

@ -0,0 +1,145 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi;
using NLog;
using NLog.Extensions.Logging;
using NLog.Web;
using System.Reflection;
using UCPlatform.API.Infrastructure;
using UCPlatform.Application;
using UCPlatform.Store;
namespace UCPlatform.API;
public class Program
{
public static void Main(string[] args)
{
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main");
try
{
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
builder.Services.AddHttpContextAccessor();
builder.Services.AddControllers();
builder.Services.AddSingleton(builder.Configuration);
#region Cors
var isconfig = builder.Configuration.GetSection("IdentityClientConfig").Get<IdentityClientConfig>();
builder.Services.AddCors(options =>
{
options.AddPolicy("_myAllowSpecificOrigins",
builder =>
{
builder
// .WithOrigins(isconfig.CorsWithOrigins) //被允许的来源,多个使用逗号分隔
.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
#region Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new ConfigureAutofac());
});
#endregion Autofac
// 开发环境宽松策略;生产再收紧
builder.Services.AddCors(options =>
{
options.AddPolicy("DevCors", policy =>
{
// 如果不走 Cookie/鉴权,最简单:
policy
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.SetPreflightMaxAge(TimeSpan.FromHours(1));
});
});
// 设置全局默认请求体大小限制
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 200 * 1024 * 1024; // 默认 200MB
});
builder.Services.AddLogging(m => { m.AddNLog(); });
builder.Services.AddDbContext<FusionDbContext>(Options =>
{
Options.UseMySql(builder.Configuration.GetConnectionString("FusionDbContext"), new MySqlServerVersion(new Version(8, 0, 19)));
Options.EnableDetailedErrors();
}, ServiceLifetime.Scoped);
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "WeiCloud.IoT-v1.0");
});
}
app.MapDefaultEndpoints();
// Configure the HTTP request pipeline.
// app.UseAuthorization();
app.MapControllers();
// 创建 Startup 实例
var startup = new Startup(builder.Configuration);
startup.Configure(app, app.Environment, builder.Configuration);
app.Run();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
logger.Error(ex, "Stopped program because of exception");
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
}

@ -0,0 +1,52 @@
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5046"
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7162;http://localhost:5046"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Container (Dockerfile)": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_HTTPS_PORTS": "8081",
"ASPNETCORE_HTTP_PORTS": "8080"
},
"publishAllPorts": true,
"useSSL": true
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:2358",
"sslPort": 44364
}
}
}

@ -0,0 +1,20 @@
using WeiCloud.Utils.Common;
namespace UCPlatform.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;
}
}
}

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\AspireApp\Manage.AppHost.ServiceDefaults\Manage.AppHost.ServiceDefaults.csproj" />
<ProjectReference Include="..\..\Common.SharedService\Common.Shared.Application\Common.Shared.Application.csproj" />
<ProjectReference Include="..\UCPlatform.Application\UCPlatform.Application.csproj" />
<ProjectReference Include="..\UCPlatform.DomainService\UCPlatform.DomainService.csproj" />
<ProjectReference Include="..\UCPlatform.Store\UCPlatform.Store.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,6 @@
@UCPlatform.API_HostAddress = http://localhost:5046
GET {{UCPlatform.API_HostAddress}}/weatherforecast/
Accept: application/json
###

@ -0,0 +1,12 @@
namespace UCPlatform.API;
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}

@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"FusionDbContext": "server=demo.weienergy.cn;uid=root;pwd=Zrhdb##2022;port=3306;database=WeiCloud.Fusion;default command timeout=100;CharSet=utf8;SslMode=None;allowPublicKeyRetrieval=true"
}
}

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace UCPlatform.Application
{
public class IdentityClientConfig
{
public string Scheme { get; set; } = string.Empty;
public string Authority { get; set; } = string.Empty;
public bool RequireHttpsMetadata { get; set; }
public string ApiName { get; set; } = string.Empty;
public string[] CorsWithOrigins { get; set; } = [];
public string ClientSecret { get; set; } = string.Empty;
public string ClientId { get; set; } = string.Empty;
public string Scope { get; set; } = string.Empty;
public string GrantType { get; set; } = string.Empty;
}
public class IdentityClientConfigV4
{
public string PolicyScheme { get; set; } = string.Empty;
public List<IdentityClientConfigItemV4> Items { get; set; } = [];
}
public class IdentityClientConfigItemV4
{
public string Scheme { get; set; } = string.Empty;
public string Authority { get; set; } = string.Empty;
public bool RequireHttpsMetadata { get; set; }
}
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,19 @@
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.AspNetCore.Mvc;
namespace UCPlatform.DomainService
{
public interface IRdsUserInfoManagerService
{
//新增或编辑
Task<ApiResult<bool>> AddorEditRdsUserAsync(AddorEditRdsUserReqDto reqDto);
//查询
Task<ApiResult<List<RdsUserInfoResDto>>> GetRdsUserInfo([FromQuery] RdsUserReqDto dto);
//删除
Task<ApiResult<bool>> DeleteRdsUserAsync([FromQuery] RdsUserReqDto dto);
}
}

@ -0,0 +1,282 @@
using Common.Shared.Application.BaseModels;
using Common.Shared.Application.SafetyFirePro.RequestDto;
using Common.Shared.Application.SafetyFirePro.ResponseDto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using UCPlatform.Entities.Model;
using UCPlatform.Store;
using WeiCloud.Core.Extension;
using WeiCloud.Utils.Common;
namespace UCPlatform.DomainService
{
public class RdsUserInfoManagerService : IRdsUserInfoManagerService
{
private readonly ILogger<RdsUserInfoManagerService> _logger;
private readonly FusionDbContext _fusionDb;
public RdsUserInfoManagerService(ILogger<RdsUserInfoManagerService> logger, FusionDbContext fusionDb)
{
_logger = logger;
_fusionDb = fusionDb;
}
#region 新增/编辑RDS用户信息
public async Task<ApiResult<bool>> AddorEditRdsUserAsync(AddorEditRdsUserReqDto reqDto)
{
try
{
// 参数验证
if (reqDto == null)
{
_logger.LogWarning("AddorEditRdsUserAsync: 请求参数为空");
return ApiResult<bool>.IsBadReq("请求参数不能为空");
}
// 验证必填字段
if (string.IsNullOrWhiteSpace(reqDto.RdsUserId))
{
return ApiResult<bool>.IsBadReq("融合通信调度用户ID不能为空");
}
if (string.IsNullOrWhiteSpace(reqDto.RdsUserPhorex))
{
return ApiResult<bool>.IsBadReq("手机号不能为空");
}
if (string.IsNullOrWhiteSpace(reqDto.RdsUserName))
{
return ApiResult<bool>.IsBadReq("用户名不能为空");
}
if (string.IsNullOrWhiteSpace(reqDto.RdsUserAccount))
{
return ApiResult<bool>.IsBadReq("账号不能为空");
}
// 根据Id判断是新增还是编辑
if (reqDto.Id.HasValue && reqDto.Id.Value > 0)
{
// 编辑操作
return await EditRdsUserAsync(reqDto);
}
else
{
// 新增操作
return await AddRdsUserAsync(reqDto);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "AddorEditRdsUserAsync: 处理RDS用户信息时发生异常,请求参数: {@ReqDto}", reqDto);
return ApiResult<bool>.IsFail("处理RDS用户信息时发生异常");
}
}
private async Task<ApiResult<bool>> AddRdsUserAsync(AddorEditRdsUserReqDto reqDto)
{
try
{
// 检查唯一约束
var existingUser = await _fusionDb.RdsSafetyUsers
.FirstOrDefaultAsync(u => u.RdsUserId == reqDto.RdsUserId ||
u.RdsUserPhorex == reqDto.RdsUserPhorex ||
u.SafetyUserId == reqDto.SafetyUserId);
if (existingUser != null)
{
if (existingUser.RdsUserId == reqDto.RdsUserId)
{
return ApiResult<bool>.IsBadReq("融合通信调度用户ID已存在");
}
if (existingUser.RdsUserPhorex == reqDto.RdsUserPhorex)
{
return ApiResult<bool>.IsBadReq("手机号已存在");
}
if (existingUser.SafetyUserId == reqDto.SafetyUserId)
{
return ApiResult<bool>.IsBadReq("安消用户ID已存在");
}
}
// 创建新实体
var newUser = new RdsSafetyUser
{
SafetyUserId = reqDto.SafetyUserId,
RdsUserId = reqDto.RdsUserId,
RdsUserType = reqDto.RdsUserType,
RdsUserPhorex = reqDto.RdsUserPhorex,
RdsUserName = reqDto.RdsUserName,
RdsUserAccount = reqDto.RdsUserAccount,
Id = UidGenerator.Uid()
};
await _fusionDb.RdsSafetyUsers.AddAsync(newUser);
await _fusionDb.SaveChangesAsync();
_logger.LogInformation("AddRdsUserAsync: 成功新增RDS用户,用户ID: {UserId}", newUser.Id);
return ApiResult<bool>.IsSuccess(true);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "AddRdsUserAsync: 数据库更新异常,请求参数: {@ReqDto}", reqDto);
return ApiResult<bool>.IsFail("新增RDS用户时操作失败");
}
catch (Exception ex)
{
_logger.LogError(ex, "AddRdsUserAsync: 新增RDS用户时发生异常,请求参数: {@ReqDto}", reqDto);
return ApiResult<bool>.IsFail("新增RDS用户时发生异常");
}
}
private async Task<ApiResult<bool>> EditRdsUserAsync(AddorEditRdsUserReqDto reqDto)
{
try
{
// 查找现有用户
var existingUser = await _fusionDb.RdsSafetyUsers
.FirstOrDefaultAsync(u => u.Id == reqDto.Id!.Value);
if (existingUser == null)
{
_logger.LogWarning("EditRdsUserAsync: 未找到要编辑的RDS用户,ID: {UserId}", reqDto.Id!.Value);
return ApiResult<bool>.IsBadReq("未找到要编辑的RDS用户");
}
// 检查唯一约束(排除当前用户)
var duplicateUser = await _fusionDb.RdsSafetyUsers
.FirstOrDefaultAsync(u => u.Id != reqDto.Id!.Value &&
(u.RdsUserId == reqDto.RdsUserId ||
u.RdsUserPhorex == reqDto.RdsUserPhorex ||
u.SafetyUserId == reqDto.SafetyUserId));
if (duplicateUser != null)
{
if (duplicateUser.RdsUserId == reqDto.RdsUserId)
{
return ApiResult<bool>.IsBadReq("融合通信调度用户已存在");
}
if (duplicateUser.RdsUserPhorex == reqDto.RdsUserPhorex)
{
return ApiResult<bool>.IsBadReq("手机号已存在");
}
if (duplicateUser.SafetyUserId == reqDto.SafetyUserId)
{
return ApiResult<bool>.IsBadReq("安消用户已存在");
}
}
// 更新用户信息
existingUser.SafetyUserId = reqDto.SafetyUserId;
existingUser.RdsUserId = reqDto.RdsUserId;
existingUser.RdsUserType = reqDto.RdsUserType;
existingUser.RdsUserPhorex = reqDto.RdsUserPhorex;
existingUser.RdsUserName = reqDto.RdsUserName;
existingUser.RdsUserAccount = reqDto.RdsUserAccount;
_fusionDb.RdsSafetyUsers.Update(existingUser);
await _fusionDb.SaveChangesAsync();
_logger.LogInformation("EditRdsUserAsync: 成功编辑RDS用户,用户ID: {UserId}", reqDto.Id!.Value);
return ApiResult<bool>.IsSuccess(true);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "EditRdsUserAsync: 数据库更新异常,请求参数: {@ReqDto}", reqDto);
return ApiResult<bool>.IsFail("编辑RDS用户时数据库操作失败");
}
catch (Exception ex)
{
_logger.LogError(ex, "EditRdsUserAsync: 编辑RDS用户时发生异常,请求参数: {@ReqDto}", reqDto);
return ApiResult<bool>.IsFail("编辑RDS用户时发生异常");
}
}
#endregion 新增/编辑RDS用户信息
public async Task<ApiResult<bool>> DeleteRdsUserAsync(RdsUserReqDto dto)
{
ApiResult<bool> result = new ApiResult<bool>();
try
{
if (dto == null)
{
return ApiResult<bool>.IsBadReq("请求参数不能为空");
}
var userInfo = await _fusionDb.RdsSafetyUsers
.AsNoTracking()
.WhereIf(dto.RdsUserId != null, u => u.RdsUserId == dto.RdsUserId)
.WhereIf(dto.SafetyUserId != null, u => u.SafetyUserId == dto.SafetyUserId)
.FirstOrDefaultAsync();
if (userInfo == null)
{
return ApiResult<bool>.IsNoFound("未找到对应的RDS用户信息");
}
_fusionDb.RdsSafetyUsers.Remove(userInfo);
await _fusionDb.SaveChangesAsync();
return ApiResult<bool>.IsSuccess(true, "删除RDS用户信息成功");
}
catch (Exception ex)
{
_logger.LogError(ex, "DeleteRdsUserAsync: 删除RDS用户信息时发生异常,请求参数: {@Dto}", dto);
return ApiResult<bool>.IsFail("删除RDS用户信息时发生异常");
}
}
public async Task<ApiResult<List<RdsUserInfoResDto>>> GetRdsUserInfo(RdsUserReqDto dto)
{
try
{
if (dto == null)
{
return ApiResult<List<RdsUserInfoResDto>>.IsBadReq("请求参数不能为空");
}
var query = _fusionDb.RdsSafetyUsers.AsNoTracking();
// 根据SafetyUserId条件查询
if (dto.SafetyUserId.HasValue && dto.SafetyUserId.Value > 0)
{
query = query.Where(u => u.SafetyUserId == dto.SafetyUserId.Value);
}
// 根据RdsUserId条件查询
if (!string.IsNullOrWhiteSpace(dto.RdsUserId))
{
query = query.Where(u => u.RdsUserId == dto.RdsUserId);
}
var users = await query.ToListAsync();
if (users == null || users.Count == 0)
{
_logger.LogInformation("GetRdsUserInfo: 未找到匹配条件的RDS用户信息,查询条件: {@Dto}", dto);
return ApiResult<List<RdsUserInfoResDto>>.IsSuccess(new List<RdsUserInfoResDto>());
}
// 映射到响应DTO
var result = users.Select(u => new RdsUserInfoResDto
{
Id = u.Id,
SafetyUserId = u.SafetyUserId,
RdsUserId = u.RdsUserId,
RdsUserType = u.RdsUserType,
RdsUserPhorex = u.RdsUserPhorex,
RdsUserName = u.RdsUserName,
RdsUserAccount = u.RdsUserAccount
}).ToList();
_logger.LogInformation("GetRdsUserInfo: 查询成功,返回{Count}条记录", result.Count);
return ApiResult<List<RdsUserInfoResDto>>.IsSuccess(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "GetRdsUserInfo: 查询RDS用户信息时发生异常,查询条件: {@Dto}", dto);
return ApiResult<List<RdsUserInfoResDto>>.IsFail("查询RDS用户信息时发生异常");
}
}
}
}

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Common.SharedService\Common.Shared.Application\Common.Shared.Application.csproj" />
<ProjectReference Include="..\..\UCPlatform.Entities\UCPlatform.Entities.csproj" />
<ProjectReference Include="..\..\WeiCloud.Core\WeiCloud.Core.csproj" />
<ProjectReference Include="..\UCPlatform.Store\UCPlatform.Store.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,73 @@
using Microsoft.EntityFrameworkCore;
using UCPlatform.Entities.Model;
namespace UCPlatform.Store;
public partial class FusionDbContext : DbContext
{
public FusionDbContext()
{
}
public FusionDbContext(DbContextOptions<FusionDbContext> options)
: base(options)
{
}
public virtual DbSet<RdsSafetyUser> RdsSafetyUsers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.UseCollation("utf8mb4_0900_ai_ci")
.HasCharSet("utf8mb4");
modelBuilder.Entity<RdsSafetyUser>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
entity.ToTable("rds_safety_user");
entity.HasIndex(e => new { e.SafetyUserId, e.RdsUserId, e.RdsUserPhorex, e.RdsUserName, e.RdsUserAccount }, "info");
entity.HasIndex(e => e.RdsUserId)
.IsUnique();
entity.HasIndex(e => e.RdsUserPhorex)
.IsUnique();
entity.HasIndex(e => e.SafetyUserId)
.IsUnique();
entity.Property(e => e.Id)
.ValueGeneratedNever()
.HasComment("主键")
.HasColumnName("id");
entity.Property(e => e.RdsUserAccount)
.HasMaxLength(50)
.HasComment("融合通信账号")
.HasColumnName("rds_user_account");
entity.Property(e => e.RdsUserId)
.HasMaxLength(50)
.HasComment("融合通信调度用户")
.HasColumnName("rds_user_id");
entity.Property(e => e.RdsUserName)
.HasMaxLength(20)
.HasComment("融合通信用户名")
.HasColumnName("rds_user_name");
entity.Property(e => e.RdsUserPhorex)
.HasMaxLength(50)
.HasComment("融合通信中用户手机号,唯一不可重复纯数字")
.HasColumnName("rds_user_phorex");
entity.Property(e => e.RdsUserType)
.HasComment("融合通信用户类型0:其他\r\n1:调度台\r\n2:调度用户\r\n3:SIP用户\r\n4:集群网关用户\r\n5:外部用户")
.HasColumnName("rds_user_type");
entity.Property(e => e.SafetyUserId)
.HasComment("安消用户id")
.HasColumnName("safety_user_id");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.4.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\UCPlatform.Entities\UCPlatform.Entities.csproj" />
</ItemGroup>
</Project>

@ -59,8 +59,8 @@ namespace Video.API
c.SwaggerDoc("v1.0", new OpenApiInfo
{
Version = "v1.0",
Title = "WeiCloud.IoT",//左侧大标题名称
Description = "安消一体化平台",
Title = "第三方微服务平台",//左侧大标题名称
Description = "融合通信微服务",
Contact = new OpenApiContact
{
Name = "hi7t",

@ -111,7 +111,6 @@ namespace Video.DomainService
/// <exception cref="NotImplementedException"></exception>
public async Task<DaHApiResult<RecordsResDto>> QueryRecords(RtspPlayBackReqDto dto)
{
// 0) 参数校验 + 早退(按需增加更多必填校验)
if (dto == null)
{
return new DaHApiResult<RecordsResDto> { Success = false, Code = "2005", Msg = "查询普通录像信息列表异常" };
@ -127,13 +126,13 @@ namespace Video.DomainService
using var req = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = JsonContent.Create(dto) // 关键:把 dto 放进请求体
Content = JsonContent.Create(dto)
};
req.Headers.TryAddWithoutValidation("Authorization", token);
try
{
using var resp = await _http.SendAsync(req); // 关键:用 SendAsync 发送 req,才能带上头
using var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
await using var stream = await resp.Content.ReadAsStreamAsync();

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WeiCloud.Core.Extension
{
public class FriendlyException : Exception
{
public FriendlyException(string friendlyMessage) : base(friendlyMessage)
{
}
public FriendlyException(string friendlyMessage, Exception innerException) : base(friendlyMessage, innerException)
{
}
}
}

@ -0,0 +1,83 @@
//using Google.Protobuf.WellKnownTypes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using WeiCloud.Entity.LogicModels.BaseModels;
namespace WeiCloud.Core.Extension
{
public static class IQueryableExtensions
{
public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
{
return condition
? query.Where(predicate)
: query;
}
public static IQueryable<T> TakePage<T>(this IQueryable<T> source, int pageSize, int pageIndex) => source.Skip((pageIndex - 1) * pageSize).Take(pageSize);
/// <summary>
/// 动态添加多个 OR 条件
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="query">查询对象</param>
/// <param name="conditions">条件列表</param>
/// <returns>包含动态 OR 条件的查询对象</returns>
public static IQueryable<T> WhereAny<T>(this IQueryable<T> query, IEnumerable<Expression<Func<T, bool>>> conditions)
{
if (conditions == null || !conditions.Any())
return query;
// 动态构建 OR 条件
Expression<Func<T, bool>> combinedCondition = null;
foreach (var condition in conditions)
{
if (combinedCondition == null)
{
combinedCondition = condition; // 第一个条件
}
else
{
// 使用 Expression.OrElse 连接条件
var newCondition = Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
combinedCondition.Body,
new ReplaceParameterVisitor(condition.Parameters[0], combinedCondition.Parameters[0]).Visit(condition.Body)
),
combinedCondition.Parameters
);
combinedCondition = newCondition;
}
}
return query.Where(combinedCondition);
}
/// <summary>
/// 用于替换表达式参数的帮助类
/// </summary>
private class ReplaceParameterVisitor : ExpressionVisitor
{
private readonly ParameterExpression _oldParameter;
private readonly ParameterExpression _newParameter;
public ReplaceParameterVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
{
_oldParameter = oldParameter;
_newParameter = newParameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node == _oldParameter)
return _newParameter;
return base.VisitParameter(node);
}
}
}
}

@ -0,0 +1,198 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace WeiCloud.Core.Extension
{
public static class TryConvertExtension
{
#region 类型转换
/// <summary>
/// string转int
/// </summary>
/// <param name="input">输入</param>
/// <param name="defaultNum">转换失败默认</param>
/// <returns></returns>
public static int TryInt(this object input, int defaultNum = 0)
{
if (input == null)
{
return defaultNum;
}
return int.TryParse(input.ToString(), out var num) ? num : defaultNum;
}
/// <summary>
/// string转long
/// </summary>
/// <param name="input">输入</param>
/// <param name="defaultNum">转换失败默认</param>
/// <returns></returns>
public static long TryLong(this object input, long defaultNum = 0)
{
if (input == null)
{
return defaultNum;
}
return long.TryParse(input.ToString(), out var num) ? num : defaultNum;
}
/// <summary>
/// string转double
/// </summary>
/// <param name="input">输入</param>
/// <param name="defaultNum">转换失败默认值</param>
/// <returns></returns>
public static double TryDouble(this object input, double defaultNum = 0)
{
if (input == null)
{
return defaultNum;
}
return double.TryParse(input.ToString(), out var num) ? num : defaultNum;
}
/// <summary>
/// string转decimal
/// </summary>
/// <param name="input">输入</param>
/// <param name="defaultNum">转换失败默认值</param>
/// <returns></returns>
public static decimal TryDecimal(this object? input, decimal defaultNum = 0)
{
if (input == null)
{
return defaultNum;
}
return decimal.TryParse(input.ToString(), out decimal num) ? num : defaultNum;
}
/// <summary>
/// string转decimal
/// </summary>
/// <param name="input">输入</param>
/// <param name="defaultNum">转换失败默认值</param>
/// <returns></returns>
public static float TryFloat(this object input, float defaultNum = 0)
{
if (input == null)
{
return defaultNum;
}
return float.TryParse(input.ToString(), out var num) ? num : defaultNum;
}
/// <summary>
/// string转bool
/// </summary>
/// <param name="input">输入</param>
/// <param name="falseVal"></param>
/// <param name="defaultBool">转换失败默认值</param>
/// <param name="trueVal"></param>
/// <returns></returns>
public static bool TryBool(this object input, bool defaultBool = false, string trueVal = "1", string falseVal = "0")
{
if (input == null)
{
return defaultBool;
}
var str = input.ToString();
if (bool.TryParse(str, out var outBool))
{
return outBool;
}
outBool = defaultBool;
if (trueVal == str)
{
return true;
}
if (falseVal == str)
{
return false;
}
return outBool;
}
/// <summary>
/// 值类型转string
/// </summary>
/// <param name="inputObj">输入</param>
/// <param name="defaultStr">转换失败默认值</param>
/// <returns></returns>
public static string TryString(this ValueType inputObj, string defaultStr = "")
{
var output = inputObj == null ? defaultStr : inputObj.ToString();
return output;
}
/// <summary>
/// 字符串转时间
/// </summary>
/// <param name="inputStr">输入</param>
/// <param name="defaultValue">默认值</param>
/// <returns></returns>
public static DateTime TryDateTime(this string inputStr, DateTime defaultValue = default)
{
if (inputStr.IsNullOrEmpty())
{
return defaultValue;
}
try
{
var result = DateTime.TryParse(inputStr, out var outPutDateTime);
if (result)
{
return outPutDateTime;
}
return DateTime.FromOADate(double.Parse(inputStr));
}
catch
{
return defaultValue;
}
}
/// <summary>
/// 字符串转时间
/// </summary>
/// <param name="inputStr">输入</param>
/// <param name="formater"></param>
/// <param name="defaultValue">默认值</param>
/// <returns></returns>
public static DateTime TryDateTime(this string inputStr, string formater, DateTime defaultValue = default)
{
if (inputStr.IsNullOrEmpty())
{
return defaultValue;
}
return DateTime.TryParseExact(inputStr, formater, CultureInfo.InvariantCulture, DateTimeStyles.None, out var outPutDateTime) ? outPutDateTime : defaultValue;
}
/// <summary>
/// 字符串去空格
/// </summary>
/// <param name="inputStr">输入</param>
/// <returns></returns>
public static string TryTrim(this string inputStr)
{
var output = inputStr.IsNullOrEmpty() ? inputStr : inputStr.Trim();
return output;
}
/// <summary>
/// 字符串转枚举
/// </summary>
/// <typeparam name="T">输入</typeparam>
/// <param name="str"></param>
/// <param name="t"></param>
/// <returns></returns>
public static T TryEnum<T>(this string str, T t = default) where T : struct
{
return Enum.TryParse<T>(str, out var result) ? result : t;
}
#endregion
}
}

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36310.24
# Visual Studio Version 18
VisualStudioVersion = 18.3.11222.16 d18.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspireApp", "AspireApp", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
@ -73,9 +73,24 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThirdPartyServices.Applicat
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThirdPartyServices.Entity", "ThirdPartyServices\ThirdPartyServices.Entity\ThirdPartyServices.Entity.csproj", "{53A7A11F-729C-4A56-BEA7-52D7080C86E2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RichCommunicationServices", "RichCommunicationServices", "{0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UC_PlatformServices", "UC_PlatformServices", "{0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}"
ProjectSection(SolutionItems) = preProject
ReadME.md = ReadME.md
UC_PlatformServices\ReadME.md = UC_PlatformServices\ReadME.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCPlatform.API", "UC_PlatformServices\UCPlatform.API\UCPlatform.API.csproj", "{210E647B-9711-4581-2A1D-667AF449B16B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCPlatform.Application", "UC_PlatformServices\UCPlatform.Application\UCPlatform.Application.csproj", "{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCPlatform.DomainService", "UC_PlatformServices\UCPlatform.DomainService\UCPlatform.DomainService.csproj", "{DCDC8802-7FAE-49D0-B6F2-5806B956FF92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCPlatform.Entities", "UCPlatform.Entities\UCPlatform.Entities.csproj", "{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCPlatform.Store", "UC_PlatformServices\UCPlatform.Store\UCPlatform.Store.csproj", "{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{ABD13595-0157-4FFA-B536-34DD415DE050}"
ProjectSection(SolutionItems) = preProject
ReadMe.md = ReadMe.md
EndProjectSection
EndProject
Global
@ -188,6 +203,26 @@ Global
{53A7A11F-729C-4A56-BEA7-52D7080C86E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53A7A11F-729C-4A56-BEA7-52D7080C86E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53A7A11F-729C-4A56-BEA7-52D7080C86E2}.Release|Any CPU.Build.0 = Release|Any CPU
{210E647B-9711-4581-2A1D-667AF449B16B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{210E647B-9711-4581-2A1D-667AF449B16B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{210E647B-9711-4581-2A1D-667AF449B16B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{210E647B-9711-4581-2A1D-667AF449B16B}.Release|Any CPU.Build.0 = Release|Any CPU
{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB}.Release|Any CPU.Build.0 = Release|Any CPU
{DCDC8802-7FAE-49D0-B6F2-5806B956FF92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCDC8802-7FAE-49D0-B6F2-5806B956FF92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCDC8802-7FAE-49D0-B6F2-5806B956FF92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCDC8802-7FAE-49D0-B6F2-5806B956FF92}.Release|Any CPU.Build.0 = Release|Any CPU
{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC}.Release|Any CPU.Build.0 = Release|Any CPU
{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -219,6 +254,11 @@ Global
{2A33E53C-E4C0-491D-8B14-BF137ECECA83} = {EDE1A83A-1BCD-4A9A-9732-AAAC2AE46216}
{7BC20C1A-33DA-4EFD-A61E-9BC7B3749023} = {EDE1A83A-1BCD-4A9A-9732-AAAC2AE46216}
{53A7A11F-729C-4A56-BEA7-52D7080C86E2} = {EDE1A83A-1BCD-4A9A-9732-AAAC2AE46216}
{210E647B-9711-4581-2A1D-667AF449B16B} = {0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}
{3F3A5EA1-22A2-4D54-A4D6-974E0E55A8BB} = {0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}
{DCDC8802-7FAE-49D0-B6F2-5806B956FF92} = {0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}
{D91A4FE1-99CD-46F1-8DED-04D33E91C3CC} = {0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}
{CF851DF8-5E5C-4785-B6F0-93E06C39EAD3} = {0F7F9FEE-200F-4080-ABF7-FC766A2D3AC6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {379A56DA-D3F0-4E7E-8FF7-DA8E20015BF3}

Loading…
Cancel
Save