diff --git a/WeiCloud.Fusion/.dockerignore b/WeiCloud.Fusion/.dockerignore new file mode 100644 index 0000000..fe1152b --- /dev/null +++ b/WeiCloud.Fusion/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs index 8075153..b22d34c 100644 --- a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs @@ -17,7 +17,10 @@ namespace Alarm.DomainService.DahAlarm private readonly MQTTClient _mqttClient; private readonly IMqttClientService _mqttClientService; private readonly ITokenProviderService _tokenProviderService; + + // private readonly HttpClient _http; private string mqttHostIp; + private int mqttHostPort; private int mqttTimeout; private string mqttUsername; @@ -32,7 +35,7 @@ namespace Alarm.DomainService.DahAlarm /// /// /// - public DahuaGeneralCtlService(ILogger logger, IConfiguration configuration, MQTTClient mQTTClient, IMqttClientService mqttClientService, ITokenProviderService tokenProviderService) + public DahuaGeneralCtlService(ILogger logger, IConfiguration configuration, MQTTClient mQTTClient, IMqttClientService mqttClientService, ITokenProviderService tokenProviderService, HttpClient http) { _logger = logger; _configuration = configuration; @@ -47,6 +50,7 @@ namespace Alarm.DomainService.DahAlarm topicName = _configuration["SubscribeMQTT:TopicName"]!; _mqttClientService = mqttClientService; _tokenProviderService = tokenProviderService; + // _http = http; } /// @@ -284,8 +288,8 @@ namespace Alarm.DomainService.DahAlarm _logger.LogWarning("获取事件列表:token无效"); return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" }; } - // var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-brm/1.0.0/device/1000014"; - var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-event/1.0.0/subscribe/subscribe-list?monitorType=url&category={name}"; + var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-brm/1.0.0/device/1000021"; + //var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-event/1.0.0/subscribe/subscribe-list?monitorType=url&category={name}"; try { diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/.config/dotnet-tools.json b/WeiCloud.Fusion/AlarmService/AlarmService.API/.config/dotnet-tools.json new file mode 100644 index 0000000..837b189 --- /dev/null +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "9.0.8", + "commands": [ + "dotnet-ef" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/AlarmService.API.csproj b/WeiCloud.Fusion/AlarmService/AlarmService.API/AlarmService.API.csproj index c867cbb..8b7c00c 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/AlarmService.API.csproj +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/AlarmService.API.csproj @@ -5,6 +5,9 @@ enable enable True + 73a07bbb-9adc-481b-9e17-d583da60d474 + Linux + ..\.. @@ -17,6 +20,7 @@ + diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Dockerfile b/WeiCloud.Fusion/AlarmService/AlarmService.API/Dockerfile new file mode 100644 index 0000000..6cde330 --- /dev/null +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Dockerfile @@ -0,0 +1,52 @@ +# ===== build 阶段 ===== +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src + +# 只拷贝 .csproj 做还原,最大化缓存命中 +COPY ["AlarmService/AlarmService.API/AlarmService.API.csproj", "AlarmService/AlarmService.API/"] +COPY ["Common.SharedService/Common.Shared.Application/Common.Shared.Application.csproj", "Common.SharedService/Common.Shared.Application/"] +COPY ["WeiCloud.Core/WeiCloud.Core.csproj", "WeiCloud.Core/"] +COPY ["WeiCloud.Utils/WeiCloud.Utils.csproj", "WeiCloud.Utils/"] +COPY ["AlarmService/Alarm.Application/Alarm.Application.csproj", "AlarmService/Alarm.Application/"] +COPY ["AlarmService/Alarm.DomainService/Alarm.DomainService.csproj", "AlarmService/Alarm.DomainService/"] +COPY ["Common.SharedService/Common.Shared.DomainService/Common.Shared.DomainService.csproj", "Common.SharedService/Common.Shared.DomainService/"] + +RUN dotnet restore "AlarmService/AlarmService.API/AlarmService.API.csproj" + +# 再拷贝全部源码并发布(一次 publish 即可) +COPY . . +RUN dotnet publish "AlarmService/AlarmService.API/AlarmService.API.csproj" \ + -c Release -o /app \ + /p:PublishReadyToRun=true \ + /p:UseAppHost=false + +# ===== runtime 阶段 ===== +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final +WORKDIR /app + +# 健康检查工具 +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +# 创建非 root 账户(存在则跳过,避免重复构建报错) +RUN set -eux; \ + if ! getent group app >/dev/null; then groupadd -g 64198 app; fi; \ + if ! id -u appuser >/dev/null 2>&1; then useradd -r -u 64198 -g app appuser; fi + +# 拷贝发布产物并赋权 +COPY --from=build /app ./ +RUN chown -R appuser:app /app + +# 对外只走 8080,TLS 在 Nginx 统一终止 +ENV ASPNETCORE_URLS=http://+:8080 \ + ASPNETCORE_ENVIRONMENT=Production +EXPOSE 8080 + +# 健康检查:你的服务需提供 /healthz +HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ + CMD curl -fsS http://localhost:8080/healthz || exit 1 + +# 以非 root 运行 +USER appuser + +ENTRYPOINT ["dotnet", "AlarmService.API.dll"] diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Program.cs b/WeiCloud.Fusion/AlarmService/AlarmService.API/Program.cs index 357545a..cd8821f 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/Program.cs +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Program.cs @@ -117,6 +117,8 @@ namespace AlarmService.API app.UseAuthorization(); app.MapControllers(); + app.MapGet("/healthz", () => Results.Ok("OK")); + // Startup ʵ var startup = new Startup(builder.Configuration); startup.Configure(app, app.Environment, builder.Configuration); diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Properties/launchSettings.json b/WeiCloud.Fusion/AlarmService/AlarmService.API/Properties/launchSettings.json index b4be839..d00ee37 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/Properties/launchSettings.json +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Properties/launchSettings.json @@ -1,33 +1,24 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:49511", - "sslPort": 44376 - } - }, +{ "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5283", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5283" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "https://localhost:7230;http://localhost:5283", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7230;http://localhost:5283" }, "IIS Express": { "commandName": "IISExpress", @@ -36,6 +27,26 @@ "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:49511", + "sslPort": 44376 } } } \ No newline at end of file diff --git a/WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/docker-compose.yml b/WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/docker-compose.yml new file mode 100644 index 0000000..3c47d26 --- /dev/null +++ b/WeiCloud.Fusion/AspireApp/Manage.AppHost.AppHost/docker-compose.yml @@ -0,0 +1,32 @@ + +version: "3.9" + +services: + video-api: + image: lxxh1992/video-api:${VIDEO_TAG:-1.1} + container_name: video-api + restart: always + environment: + - ASPNETCORE_ENVIRONMENT=Production + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:8080/healthz"] + interval: 30s + timeout: 3s + retries: 3 + # 仅绑定到本机回环,避免对公网暴露端口 + ports: + - "127.0.0.1:5001:8080" + + alarmservice-api: + image: lxxh1992/alarmservice-api:${ALARM_TAG:-1.1} + container_name: alarmservice-api + restart: always + environment: + - ASPNETCORE_ENVIRONMENT=Production + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:8080/healthz"] + interval: 30s + timeout: 3s + retries: 3 + ports: + - "127.0.0.1:5002:8080" diff --git a/WeiCloud.Fusion/ParkingLotService/ParkingLotService.API/Dockerfile b/WeiCloud.Fusion/ParkingLotService/ParkingLotService.API/Dockerfile new file mode 100644 index 0000000..6cde330 --- /dev/null +++ b/WeiCloud.Fusion/ParkingLotService/ParkingLotService.API/Dockerfile @@ -0,0 +1,52 @@ +# ===== build 阶段 ===== +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src + +# 只拷贝 .csproj 做还原,最大化缓存命中 +COPY ["AlarmService/AlarmService.API/AlarmService.API.csproj", "AlarmService/AlarmService.API/"] +COPY ["Common.SharedService/Common.Shared.Application/Common.Shared.Application.csproj", "Common.SharedService/Common.Shared.Application/"] +COPY ["WeiCloud.Core/WeiCloud.Core.csproj", "WeiCloud.Core/"] +COPY ["WeiCloud.Utils/WeiCloud.Utils.csproj", "WeiCloud.Utils/"] +COPY ["AlarmService/Alarm.Application/Alarm.Application.csproj", "AlarmService/Alarm.Application/"] +COPY ["AlarmService/Alarm.DomainService/Alarm.DomainService.csproj", "AlarmService/Alarm.DomainService/"] +COPY ["Common.SharedService/Common.Shared.DomainService/Common.Shared.DomainService.csproj", "Common.SharedService/Common.Shared.DomainService/"] + +RUN dotnet restore "AlarmService/AlarmService.API/AlarmService.API.csproj" + +# 再拷贝全部源码并发布(一次 publish 即可) +COPY . . +RUN dotnet publish "AlarmService/AlarmService.API/AlarmService.API.csproj" \ + -c Release -o /app \ + /p:PublishReadyToRun=true \ + /p:UseAppHost=false + +# ===== runtime 阶段 ===== +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final +WORKDIR /app + +# 健康检查工具 +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +# 创建非 root 账户(存在则跳过,避免重复构建报错) +RUN set -eux; \ + if ! getent group app >/dev/null; then groupadd -g 64198 app; fi; \ + if ! id -u appuser >/dev/null 2>&1; then useradd -r -u 64198 -g app appuser; fi + +# 拷贝发布产物并赋权 +COPY --from=build /app ./ +RUN chown -R appuser:app /app + +# 对外只走 8080,TLS 在 Nginx 统一终止 +ENV ASPNETCORE_URLS=http://+:8080 \ + ASPNETCORE_ENVIRONMENT=Production +EXPOSE 8080 + +# 健康检查:你的服务需提供 /healthz +HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ + CMD curl -fsS http://localhost:8080/healthz || exit 1 + +# 以非 root 运行 +USER appuser + +ENTRYPOINT ["dotnet", "AlarmService.API.dll"] diff --git a/WeiCloud.Fusion/VideoService/Video.API/Dockerfile b/WeiCloud.Fusion/VideoService/Video.API/Dockerfile new file mode 100644 index 0000000..726177d --- /dev/null +++ b/WeiCloud.Fusion/VideoService/Video.API/Dockerfile @@ -0,0 +1,52 @@ +# ===== build 阶段 ===== +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src + +# 仅拷贝 csproj 提升缓存命中 +COPY ["VideoService/Video.API/Video.API.csproj", "VideoService/Video.API/"] +COPY ["Common.SharedService/Common.Shared.Application/Common.Shared.Application.csproj", "Common.SharedService/Common.Shared.Application/"] +COPY ["WeiCloud.Core/WeiCloud.Core.csproj", "WeiCloud.Core/"] +COPY ["WeiCloud.Utils/WeiCloud.Utils.csproj", "WeiCloud.Utils/"] +COPY ["VideoService/Video.Application/Video.Application.csproj", "VideoService/Video.Application/"] +COPY ["VideoService/Video.DomainService/Video.DomainService.csproj", "VideoService/Video.DomainService/"] +COPY ["Common.SharedService/Common.Shared.DomainService/Common.Shared.DomainService.csproj", "Common.SharedService/Common.Shared.DomainService/"] + +RUN dotnet restore "VideoService/Video.API/Video.API.csproj" + +# 再拷贝全部源码并发布 +COPY . . +RUN dotnet publish "VideoService/Video.API/Video.API.csproj" \ + -c Release -o /app \ + /p:PublishReadyToRun=true \ + /p:UseAppHost=false + +# ===== runtime 阶段 ===== +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final +WORKDIR /app + +# 健康检查用 curl +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +# 创建非 root 账户(存在则跳过) +RUN set -eux; \ + if ! getent group app >/dev/null; then groupadd -g 64198 app; fi; \ + if ! id -u appuser >/dev/null 2>&1; then useradd -r -u 64198 -g app appuser; fi + +# 拷贝发布产物并赋权 +COPY --from=build /app ./ +RUN chown -R appuser:app /app + +# 对外只走 8080,TLS 在 Nginx 统一终止 +ENV ASPNETCORE_URLS=http://+:8080 \ + ASPNETCORE_ENVIRONMENT=Production +EXPOSE 8080 + +# 健康检查:需要你的服务实现 /healthz +HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ + CMD curl -fsS http://localhost:8080/healthz || exit 1 + +# 以非 root 运行 +USER appuser + +ENTRYPOINT ["dotnet", "Video.API.dll"] diff --git a/WeiCloud.Fusion/VideoService/Video.API/Program.cs b/WeiCloud.Fusion/VideoService/Video.API/Program.cs index f91072e..45bc79b 100644 --- a/WeiCloud.Fusion/VideoService/Video.API/Program.cs +++ b/WeiCloud.Fusion/VideoService/Video.API/Program.cs @@ -113,6 +113,20 @@ namespace Video.API #endregion CAPע + // ɲԣս + builder.Services.AddCors(options => + { + options.AddPolicy("DevCors", policy => + { + // Cookie/Ȩ򵥣 + policy + .AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod() + .SetPreflightMaxAge(TimeSpan.FromHours(1)); + }); + }); + // ȫĬС builder.WebHost.ConfigureKestrel(options => { @@ -139,6 +153,7 @@ namespace Video.API app.UseHttpsRedirection(); app.UseAuthorization(); + app.MapGet("/healthz", () => Results.Ok("OK")); app.MapControllers(); // Startup ʵ diff --git a/WeiCloud.Fusion/VideoService/Video.API/Properties/launchSettings.json b/WeiCloud.Fusion/VideoService/Video.API/Properties/launchSettings.json index c57bfb9..75c68f3 100644 --- a/WeiCloud.Fusion/VideoService/Video.API/Properties/launchSettings.json +++ b/WeiCloud.Fusion/VideoService/Video.API/Properties/launchSettings.json @@ -1,33 +1,24 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:2357", - "sslPort": 44365 - } - }, +{ "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5224", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5224" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "https://localhost:7161;http://localhost:5224", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7161;http://localhost:5224" }, "IIS Express": { "commandName": "IISExpress", @@ -36,6 +27,26 @@ "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:2357", + "sslPort": 44365 } } -} +} \ No newline at end of file diff --git a/WeiCloud.Fusion/VideoService/Video.API/Video.API.csproj b/WeiCloud.Fusion/VideoService/Video.API/Video.API.csproj index 77b0250..556bbe6 100644 --- a/WeiCloud.Fusion/VideoService/Video.API/Video.API.csproj +++ b/WeiCloud.Fusion/VideoService/Video.API/Video.API.csproj @@ -5,6 +5,9 @@ enable enable True + 90a4021f-e10a-4236-abb4-4bac4779e5d1 + Linux + ..\.. @@ -12,6 +15,7 @@ + diff --git a/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs index bebad90..15f957c 100644 --- a/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs @@ -13,24 +13,25 @@ namespace Video.DomainService private readonly ILogger _logger; private readonly IConfiguration _configuration; private readonly ITokenProviderService _tokenProviderService; - // private readonly HttpClient _http; + private readonly HttpClient _http; - public DahuaGeneralCtlService(ILogger logger, IConfiguration configuration, ITokenProviderService tokenProviderService) + public DahuaGeneralCtlService(ILogger logger, IConfiguration configuration, ITokenProviderService tokenProviderService, HttpClient http) { _logger = logger; _configuration = configuration; _tokenProviderService = tokenProviderService; - //_http = http; + _http = http; + _http = http; } - /// - /// 开发测试的时候,忽略证书 - /// - private static readonly HttpClient _http = new HttpClient(new HttpClientHandler - { - ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator - }); + ///// + ///// 开发测试的时候,忽略证书 + ///// + //private static readonly HttpClient _http = new HttpClient(new HttpClientHandler + //{ + // ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + //}); /// /// hls等录像回放