定时任务修改;海运出口添加服务项目

usertest
cjy 3 months ago
parent 395ff4862f
commit 76b05e5879

@ -20,7 +20,7 @@ namespace DS.Module.HangfireModule
{
if (app == null) throw new ArgumentNullException(nameof(app));
app.UseHangfireServer(); // 用于将 Hangfire 任务处理服务器添加到请求处理管道中
//app.UseHangfireServer(); // 用于将 Hangfire 任务处理服务器添加到请求处理管道中
// 将 Hangfire 仪表板添加到应用程序的请求处理管道中
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{

@ -40,13 +40,13 @@ public static class WorkServiceHangfireModuleInstall
TransactionTimeout = TimeSpan.FromMinutes(1), //- 交易超时。默认为1分钟。
TablesPrefix = "Hangfire"
})));
services.AddHangfireServer(options =>
{
options.WorkerCount = AppSetting.app(new string[] { "HangfireSettings", "WorkerCount" }).ToInt();
options.ServerName = AppSetting.app(new string[] { "HangfireSettings", "ServerName" });
options.Queues = AppSetting.app(new string[] { "HangfireSettings", "Queues" }).Split(',');
});
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 5 });
//services.AddHangfireServer(options =>
//{
// options.WorkerCount = AppSetting.app(new string[] { "HangfireSettings", "WorkerCount" }).ToInt();
// options.ServerName = AppSetting.app(new string[] { "HangfireSettings", "ServerName" });
// options.Queues = AppSetting.app(new string[] { "HangfireSettings", "Queues" }).Split(',');
//});
//GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 5 });
services.AddHangfireServer();
}
}

@ -44,7 +44,7 @@ namespace DS.WMS.Core.HangfireJob.Method
jobComService = _serviceProvider.GetRequiredService<IJobCommonService>();
}
public async void VgmLinkJob(BaseJobReq req)
public void VgmLinkJob(BaseJobReq req)
{
var tenantDb = saasService.GetBizJobDbScopeById(req);
tenantDb.QueryFilter.Clear<IOrgId>();
@ -64,7 +64,7 @@ namespace DS.WMS.Core.HangfireJob.Method
{
BusinessId = bookingId
};
await tenantDb.Insertable(orderUrl).ExecuteCommandAsync();
tenantDb.Insertable(orderUrl).ExecuteCommand();
}
//if (!string.IsNullOrEmpty(orderUrl.UrlVgm))
@ -134,7 +134,7 @@ namespace DS.WMS.Core.HangfireJob.Method
throw new Exception("箱型EDI配置未找到{0}\", $\"{string.Join(',', expCode)}(VGM)!");
}
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == req.UserId);
var userInfo = db.Queryable<SysUser>().Filter(null, true).First(x => x.Id == req.UserId);
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == req.TenantId);
var destinationCode = jobComService.GetPortCode(order.DestinationId, tenantDb);
@ -216,7 +216,7 @@ namespace DS.WMS.Core.HangfireJob.Method
var memoData = jobjResp.GetJObjectValue("memoData");
orderUrl.UrlVgm = memoData.GetStringValue("vgmUrl");
orderUrl.UrlVgmSi = memoData.GetStringValue("vgmAndSiUrl");
await tenantDb.Updateable(orderUrl).ExecuteCommandAsync();
tenantDb.Updateable(orderUrl).ExecuteCommand();
//货运动态
@ -228,10 +228,10 @@ namespace DS.WMS.Core.HangfireJob.Method
OpTime = DateTime.Now,
MBLNO = order.MBLNO
};
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
tenantDb.Insertable(bookingStatus).ExecuteCommand();
}
public async void TxxpLinkJob(BaseJobReq req)
public void TxxpLinkJob(BaseJobReq req)
{
var tenantDb = saasService.GetBizJobDbScopeById(req);
tenantDb.QueryFilter.Clear<IOrgId>();
@ -246,7 +246,7 @@ namespace DS.WMS.Core.HangfireJob.Method
{
BusinessId = bookingId
};
await tenantDb.Insertable(orderUrl).ExecuteCommandAsync();
tenantDb.Insertable(orderUrl).ExecuteCommand();
}
//校验船公司
@ -326,7 +326,7 @@ namespace DS.WMS.Core.HangfireJob.Method
throw new Exception("箱型EDI配置未找到{0}\", $\"{string.Join(',', expCode)}(提箱小票)!");
}
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == req.UserId);
var userInfo = db.Queryable<SysUser>().Filter(null, true).First(x => x.Id == req.UserId);
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == req.TenantId);
//调用小票服务
@ -384,7 +384,7 @@ namespace DS.WMS.Core.HangfireJob.Method
//保存url
var txxpUrl = jobjResp.GetStringValue("data");
orderUrl.UrlTxxp = txxpUrl;
await tenantDb.Updateable(orderUrl).ExecuteCommandAsync();
tenantDb.Updateable(orderUrl).ExecuteCommand();
//货运动态
@ -396,7 +396,7 @@ namespace DS.WMS.Core.HangfireJob.Method
OpTime = DateTime.Now,
MBLNO = order.MBLNO
};
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
tenantDb.Insertable(bookingStatus).ExecuteCommand();
}
}
}

@ -1,4 +1,5 @@
using DS.Module.Core.Extensions;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
@ -126,5 +127,10 @@ namespace DS.WMS.Core.Info.Dtos
/// 往来单位默认联系人
/// </summary>
public ClientContactRes ClientContact { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public string? ServiceItem { get; set; }
}
}

@ -1235,6 +1235,11 @@ public class SeaExportReq
/// 所属业务部门名称
/// </summary>
public string SaleDeptName { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public string? ServiceItem { get; set; }
}
/// <summary>

@ -1453,4 +1453,9 @@ public class SeaExportRes
/// 拆票或合票标志 1-拆票 2-合票
/// </summary>
public int SplitOrMergeFlag { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public string? ServiceItem { get; set; }
}

@ -1620,4 +1620,10 @@ public class SeaExport : BaseOrgModel<long>
/// </summary>
[SqlSugar.SugarColumn(ColumnDescription = "所属业务部门名称", IsNullable = true, Length = 100)]
public string SaleDeptName { get; set; }
/// <summary>
/// 服务项目
/// </summary>
[SugarColumn(ColumnDescription = "服务项目", ColumnDataType = "text", IsNullable = true)]
public string? ServiceItem { get; set; }
}

@ -141,7 +141,6 @@ public class ClientCommonService : IClientCommonService
/// <returns></returns>
public async Task<DataResult<List<CodeCarrierRes>>> GetCarrierSelectList(string queryKey = "")
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var list = await tenantDb.Queryable<CodeCarrier>()
.WhereIF(!string.IsNullOrEmpty(queryKey), a => a.Code.Contains(queryKey) || a.CnName.Contains(queryKey))

@ -10,12 +10,17 @@ using Hangfire;
using DS.WMS.Core.HangfireJob.Interface;
using DS.WMS.Core.HangfireJob.Method;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using NLog.Web;
var builder = Host.CreateApplicationBuilder(args);
//应用作为 Windows 服务
builder.Services.AddWindowsService();
builder.Services.AddWindowsService(options =>
{
options.ServiceName = ".NET Work Service";
});
//注册配置
builder.Configuration
.AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
@ -38,15 +43,19 @@ builder.Services.AddSqlSugarInstall();
builder.Services.AddSaasDbInstall();//分库服务
//注入hangfire
builder.Services.AddWorkServiceHangfireModuleInstall();
builder.Services.AddHostedService<Worker>();
//应用作为 Windows 服务
//builder.Services.AddWindowsService();
builder.Services.AddHostedService<WindowsBackgroundService>();
//允许 BackgroundService 中存在未经处理的异常,不停止主机
builder.Services.Configure<HostOptions>(hostOptions =>
{
hostOptions.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore;
hostOptions.ServicesStartConcurrently = true;
hostOptions.ServicesStopConcurrently = true;
});
var host = builder.Build();
host.Run();

@ -0,0 +1,54 @@
using DS.WMS.Core.Code.Entity;
using Hangfire;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DS.WMS.JobService
{
public sealed class WindowsBackgroundService(
ILogger<WindowsBackgroundService> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
var _OpServer = new BackgroundJobServer(new BackgroundJobServerOptions
{
SchedulePollingInterval = TimeSpan.FromMinutes(1),
ServerName = "OpWorkService",
Queues = new[] { "op" }
});
//logger.LogWarning("{Joke}", joke);
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch (OperationCanceledException)
{
// When the stopping token is canceled, for example, a call made from services.msc,
// we shouldn't exit with a non-zero exit code. In other words, this is expected...
}
catch (Exception ex)
{
logger.LogError(ex, "{Message}", ex.Message);
// Terminates this process and returns an exit code to the operating system.
// This is required to avoid the 'BackgroundServiceExceptionBehavior', which
// performs one of two scenarios:
// 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
// 2. When set to "StopHost": will cleanly stop the host, and log errors.
//
// In order for the Windows Service Management system to leverage configured
// recovery options, we need to terminate the process with a non-zero exit code.
Environment.Exit(1);
}
}
}
}

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.WMS.Core.Code.Entity;
using Hangfire;
using Hangfire.MySql;
@ -7,25 +8,64 @@ namespace DS.WMS.JobService
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private BackgroundJobServer _server;
private BackgroundJobServer _OpServer;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
public override async Task StartAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
var options = new BackgroundJobServerOptions
_OpServer = new BackgroundJobServer(new BackgroundJobServerOptions
{
SchedulePollingInterval = TimeSpan.FromMinutes(1),
ServerName = "WorkService",
Queues = new[] { "op", "task" }
};
ServerName = "OpWorkService",
Queues = new[] { "op" }
});
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch (OperationCanceledException ex)
{
Console.WriteLine(ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
//Environment.Exit(1);
}
}
//protected override async Task StopAsync(CancellationToken stoppingToken)
//{
//}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
//var options = new BackgroundJobServerOptions
//{
// SchedulePollingInterval = TimeSpan.FromMinutes(1),
// ServerName = "WorkService",
// Queues = new[] { "op", "task" }
//};
while (!stoppingToken.IsCancellationRequested)
{
try
{
_server = new BackgroundJobServer(options);
//_server = new BackgroundJobServer(options);
//_server = new BackgroundJobServer(new BackgroundJobServerOptions
//{
// SchedulePollingInterval = TimeSpan.FromMinutes(1),
// ServerName = "WorkService",
// Queues = new[] { "op", "task" }
//});
//_server = new BackgroundJobServer();
await DoWork(stoppingToken);
Console.WriteLine("Hangfire Server started. Press any key to exit...");

@ -1,41 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DS.Module.AutofacModule\DS.Module.AutofacModule.csproj" />
<ProjectReference Include="..\DS.Module.Core\DS.Module.Core.csproj" />
<ProjectReference Include="..\DS.Module.HangfireModule\DS.Module.HangfireModule.csproj" />
<ProjectReference Include="..\DS.Module.Nuget\DS.Module.Nuget.csproj" />
<ProjectReference Include="..\DS.Module.SqlSugar\DS.Module.SqlSugar.csproj" />
<ProjectReference Include="..\DS.Module.UserModule\DS.Module.UserModule.csproj" />
<ProjectReference Include="..\DS.WMS.Core\DS.WMS.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>

@ -1,6 +0,0 @@
@DS.WMS.JobServiceApi_HostAddress = http://localhost:5063
GET {{DS.WMS.JobServiceApi_HostAddress}}/weatherforecast/
Accept: application/json
###

@ -1,56 +0,0 @@
using System.Net;
using System.Text.Json;
namespace DS.WMS.JobServiceApi
{
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next; // 用来处理上下文请求
public ExceptionHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext); //要么在中间件中处理,要么被传递到下一个中间件中去
}
catch (Exception ex)
{
await HandleExceptionAsync(httpContext, ex); // 捕获异常了 在HandleExceptionAsync中处理
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json"; // 返回json 类型
var response = context.Response;
var errorResponse = new ErrorResponse
{
Success = false,
}; // 自定义的异常错误信息类型
switch (exception)
{
default:
response.StatusCode = (int)HttpStatusCode.InternalServerError;
errorResponse.Message = exception.Message;// "Internal Server errors. Check Logs!";
break;
}
var result = JsonSerializer.Serialize(errorResponse);
await context.Response.WriteAsync(result);
}
private class ErrorResponse
{
public bool Success { get; set; } = true;
public string Message { get; set; }
}
}
}

@ -1,46 +0,0 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using DS.Module.AutofacModule;
using DS.Module.HangfireModule;
using DS.Module.RedisModule;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.JobServiceApi;
using NLog.Web;
var builder = WebApplication.CreateBuilder(args);
//注册配置
builder.Configuration
.AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
.Build();
builder.Configuration.AddEnvironmentVariables();
builder.Logging.AddNLog("nlog.config");
// Add services to the container.
//Autofac注入
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder => { builder.RegisterModule(new AutofacModuleRegister()); });
builder.Services.AddUserModuleInstall(); //用户服务
builder.Services.AddRedisModuleInstall();//redis
builder.Services.AddSqlSugarInstall();
builder.Services.AddSaasDbInstall();//分库服务
builder.Services.AddWorkServiceHangfireModuleInstall();//Hangfire服务
//允许 BackgroundService 中存在未经处理的异常,不停止主机
builder.Services.Configure<HostOptions>(hostOptions =>
{
hostOptions.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore;
}); //应用作为 Windows 服务
builder.Services.AddWindowsService();
var app = builder.Build();
//app.UseHangfireMiddleware();
//异常中间件
app.UseMiddleware<ExceptionHandlingMiddleware>();
//app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.Run();

@ -1,31 +0,0 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62943",
"sslPort": 0
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5063",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

@ -1,29 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"DBInfo": {
"DefaultDbConnId": "1288018625843826688",
"DefaultDbType": 0,
"DefaultDbString": "server=rm-m5e06xxqpa68a68ry5o.mysql.rds.aliyuncs.com;port=3306;uid=rulesengine_admin;pwd=Rule1qaz2wsx!QAZ;database=shippingweb8_dev",
"DBS": [
{
"ConnId": "1288018625843826680",
"DBType": 0,
"Enabled": false,
"HitRate": 40,
"Connection": "server=rm-m5e06xxqpa68a68ry5o.mysql.rds.aliyuncs.com;port=3306;uid=rulesengine_admin;pwd=Rule1qaz2wsx!QAZ;database=shippingweb8_log"
}
]
},
"HangfireSettings": {
"DbString": "server=rm-m5e06xxqpa68a68ry5o.mysql.rds.aliyuncs.com;port=3306;uid=rulesengine_admin;pwd=Rule1qaz2wsx!QAZ;database=shippingweb8_hangfire;Allow User Variables=true",
"WorkerCount": 10,
"ServerName": "WorkService",
"Queues": "op"
}
}

@ -1,36 +0,0 @@
<?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"
internalLogLevel="info"
internalLogFile="Logs\internal-nlog.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore" />
</extensions>
<targets>
<!-- 写入文件配置 -->
<!-- 将日志写入文件 -->
<target xsi:type="File" name="allfile" fileName="Logs\nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring} ${newline}" />
<!-- 另一个文件日志只有自己的日志。使用一些ASP.NET核心渲染器 -->
<target xsi:type="File" name="ownFile-web" fileName="Logs\nlog-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action} ${newline}" />
<!-- 将日志写入控制台 -->
<target name="console" xsi:type="ColoredConsole" layout="${longdate} ${message} ${exception:format=tostring}" />
</targets>
<rules>
<!--所有日志包括来自Microsoft的-->
<!--minlevel 改为Trace 跟踪全部 Error 只捕获异常-->
<!-- <logger name="*" minlevel="Trace" writeTo="allfile" /> -->
<logger name="*" minlevel="Trace" writeTo="console" />
<!--跳过非关键的Microsoft日志因此只记录自己的日志-->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<!-- BlackHole without writeTo -->
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>

@ -76,8 +76,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.Module.HangfireModule",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.WMS.JobService", "DS.WMS.JobService\DS.WMS.JobService.csproj", "{99B79A25-3732-4023-BD56-ABD169CE43AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DS.WMS.JobServiceApi", "DS.WMS.JobServiceApi\DS.WMS.JobServiceApi.csproj", "{7D66E0AA-92B3-45B6-8E12-058A9F2DC272}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -212,10 +210,6 @@ Global
{99B79A25-3732-4023-BD56-ABD169CE43AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99B79A25-3732-4023-BD56-ABD169CE43AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99B79A25-3732-4023-BD56-ABD169CE43AD}.Release|Any CPU.Build.0 = Release|Any CPU
{7D66E0AA-92B3-45B6-8E12-058A9F2DC272}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D66E0AA-92B3-45B6-8E12-058A9F2DC272}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D66E0AA-92B3-45B6-8E12-058A9F2DC272}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D66E0AA-92B3-45B6-8E12-058A9F2DC272}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -253,7 +247,6 @@ Global
{7C3E248A-DF40-46AC-A8DF-224DD7C4EEF7} = {65D75DB2-12D5-4D1F-893D-9750905CE5E4}
{BDF89987-3B7B-4CC6-88A9-DA4765F6FF62} = {518DB9B5-80A8-4B2C-8570-52BD406458DE}
{99B79A25-3732-4023-BD56-ABD169CE43AD} = {65D75DB2-12D5-4D1F-893D-9750905CE5E4}
{7D66E0AA-92B3-45B6-8E12-058A9F2DC272} = {65D75DB2-12D5-4D1F-893D-9750905CE5E4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {66115F23-94B4-43C0-838E-33B5CF77F788}

Loading…
Cancel
Save