新增MES模块,包含供应商、客户、车辆和地磅数据记录管理功能,支持免密接口和数据同步。更新相关控制器、实体、服务和数据库配置,优化权限管理和数据字典支持,确保系统的灵活性和可扩展性。
This commit is contained in:
@@ -7,6 +7,10 @@ using YY.Admin.Views;
|
||||
using YY.Admin.Views.Control;
|
||||
using YY.Admin.Views.Dialogs;
|
||||
using YY.Admin.Views.SysManage;
|
||||
using YY.Admin.Views.Customer;
|
||||
using YY.Admin.Views.Supplier;
|
||||
using YY.Admin.ViewModels.Vehicle;
|
||||
using YY.Admin.Views.Vehicle;
|
||||
|
||||
namespace YY.Admin
|
||||
{
|
||||
@@ -49,7 +53,14 @@ namespace YY.Admin
|
||||
containerRegistry.RegisterForNavigation<DataDictionaryManagementView>();
|
||||
containerRegistry.RegisterForNavigation<RoleManagementView>();
|
||||
containerRegistry.RegisterForNavigation<TenantManagementView>();
|
||||
|
||||
containerRegistry.RegisterForNavigation<MenuManagementView>();
|
||||
containerRegistry.RegisterForNavigation<LoginSettingsView>();
|
||||
// 车辆管理
|
||||
containerRegistry.RegisterForNavigation<VehicleListView>();
|
||||
// 客户管理
|
||||
containerRegistry.RegisterForNavigation<CustomerListView>();
|
||||
// 供应商管理
|
||||
containerRegistry.RegisterForNavigation<SupplierListView>();
|
||||
}
|
||||
}
|
||||
public class DialogWindow : Window, IDialogWindow
|
||||
|
||||
@@ -5,11 +5,17 @@ using Polly.Extensions.Http;
|
||||
using Prism.Ioc;
|
||||
using Prism.Modularity;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using YY.Admin.Core.Services;
|
||||
using YY.Admin.Core.Session;
|
||||
using YY.Admin.EventBus;
|
||||
using YY.Admin.Infrastructure.Hubs;
|
||||
using YY.Admin.Infrastructure.Network;
|
||||
using YY.Admin.Infrastructure.Storage;
|
||||
using YY.Admin.Infrastructure.Sync;
|
||||
using YY.Admin.Services.Service.Customer;
|
||||
using YY.Admin.Services.Service.Supplier;
|
||||
using YY.Admin.Services.Service.Vehicle;
|
||||
|
||||
namespace YY.Admin.Module;
|
||||
|
||||
@@ -23,8 +29,22 @@ public class SyncModule : IModule
|
||||
containerRegistry.RegisterSingleton<IJeecgUserMirrorPullOutbox, JeecgUserMirrorPullOutbox>();
|
||||
containerRegistry.RegisterSingleton<INetworkMonitor, NetworkMonitor>();
|
||||
containerRegistry.RegisterSingleton<ISignalRService, StompWebSocketService>();
|
||||
containerRegistry.RegisterSingleton<IUserSyncOutbox, UserSyncOutbox>();
|
||||
// 本地用户事件订阅器:将增删改操作入 Outbox 回传后端
|
||||
containerRegistry.RegisterSingleton<SysUserEventSubscriber>();
|
||||
|
||||
// 车辆管理:免密 API 直连 + STOMP 实时通知
|
||||
containerRegistry.RegisterSingleton<IVehicleService, VehicleService>();
|
||||
containerRegistry.RegisterSingleton<VehicleSyncCoordinator>();
|
||||
// 客户管理:免密 API 直连 + STOMP 实时通知
|
||||
containerRegistry.RegisterSingleton<ICustomerService, CustomerService>();
|
||||
containerRegistry.RegisterSingleton<CustomerSyncCoordinator>();
|
||||
// 供应商管理:免密 API 直连 + STOMP 实时通知
|
||||
containerRegistry.RegisterSingleton<ISupplierService, SupplierService>();
|
||||
containerRegistry.RegisterSingleton<SupplierSyncCoordinator>();
|
||||
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddTransient<DisconnectGuardHandler>();
|
||||
serviceCollection.AddHttpClient("JeecgApi", (sp, client) =>
|
||||
{
|
||||
var config = containerRegistry.GetContainer().Resolve<IConfiguration>();
|
||||
@@ -40,7 +60,14 @@ public class SyncModule : IModule
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
}
|
||||
}).AddPolicyHandler(GetRetryPolicy());
|
||||
client.DefaultRequestHeaders.TryAddWithoutValidation("X-Platform", "desktop");
|
||||
// .NET HttpClient 要求请求头值为 ASCII;主机名/中文姓名否则会报 Request headers must contain only ASCII characters
|
||||
client.DefaultRequestHeaders.TryAddWithoutValidation("X-Host-Name", ToAsciiHttpHeaderValue(Environment.MachineName));
|
||||
var currentUser = AppSession.CurrentUser;
|
||||
client.DefaultRequestHeaders.TryAddWithoutValidation("X-User-Name", ToAsciiHttpHeaderValue(currentUser?.Account ?? "unknown"));
|
||||
client.DefaultRequestHeaders.TryAddWithoutValidation("X-Real-Name", ToAsciiHttpHeaderValue(currentUser?.RealName ?? ""));
|
||||
}).AddPolicyHandler(GetRetryPolicy())
|
||||
.AddHttpMessageHandler<DisconnectGuardHandler>();
|
||||
|
||||
var provider = serviceCollection.BuildServiceProvider();
|
||||
var httpClientFactory = provider.GetRequiredService<IHttpClientFactory>();
|
||||
@@ -57,6 +84,14 @@ public class SyncModule : IModule
|
||||
_ = outboxProcessor.StartConsumerAsync(CancellationToken.None);
|
||||
// 用户镜像 + 设备指令:统一 STOMP(/ws/device),免密与设备 Token 模式均启动
|
||||
_ = Task.Run(() => signalService.ConnectUnifiedDeviceChannelAsync(CancellationToken.None));
|
||||
// 强制实例化事件订阅器(单例,构造函数内完成订阅注册)
|
||||
_ = containerProvider.Resolve<SysUserEventSubscriber>();
|
||||
// 强制实例化车辆同步协调器(构造函数内订阅 STOMP 车辆变更事件)
|
||||
_ = containerProvider.Resolve<VehicleSyncCoordinator>();
|
||||
// 强制实例化客户同步协调器
|
||||
_ = containerProvider.Resolve<CustomerSyncCoordinator>();
|
||||
// 强制实例化供应商同步协调器
|
||||
_ = containerProvider.Resolve<SupplierSyncCoordinator>();
|
||||
}
|
||||
|
||||
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
|
||||
@@ -66,4 +101,24 @@ public class SyncModule : IModule
|
||||
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将自定义请求头转为 ASCII(含非 ASCII 时整体做 UTF-8 Base64,前缀 B64. 便于后端按需解码)。
|
||||
/// </summary>
|
||||
private static string ToAsciiHttpHeaderValue(string? value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
foreach (var c in value)
|
||||
{
|
||||
if (c > 127)
|
||||
{
|
||||
return "B64." + Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user