# CLAUDE.md 本文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。 ## 构建命令 ```bash # 构建整个解决方案 dotnet build WIDESEAWCS_Server.sln # 构建并运行服务器 cd WIDESEAWCS_Server dotnet run # 运行测试 cd WIDESEAWCS_Tests dotnet test ``` ## 架构概述 这是一个基于 ASP.NET Core 6.0 构建的 **WCS(仓库控制系统)**,使用以下技术: - **Autofac** - 通过 `IDependency` 标记接口实现自动服务发现的依赖注入 - **Quartz.NET** - 定时任务执行(设备通信循环) - **SqlSugar ORM** - 数据库访问 - **Redis**(通过 `WIDESEAWCS_RedisService`)- 采用 L1+L2 混合模式的分布式缓存 - **StackExchange.Redis** - Redis 操作 - **TCP Socket Server** - 实时设备通信 - **HslCommunication** 库 - PLC/硬件通信 ## 项目结构 ``` WIDESEAWCS_Server/ # 主 ASP.NET Core API 服务器 WIDESEAWCS_Core/ # 核心基础设施:基类、DI、扩展、中间件 WIDESEAWCS_Model/ # 数据模型和 DTO WIDESEAWCS_Communicator/ # 硬件通信驱动(Siemens、Omron、Modbus 等) WIDESEAWCS_QuartzJob/ # 任务调度基础设施和设备抽象 WIDESEAWCS_Tasks/ # Quartz 任务实现(设备通信循环) WIDESEAWCS_RedisService/ # Redis 服务:缓存、锁、计数器、发布订阅等 WIDESEAWCS_*Repository/ # 数据访问层实现 WIDESEAWCS_*Service/ # 业务服务层 WIDESEAWCS_Tests/ # 单元测试 ``` ## 依赖注入 - IDependency 模式 服务通过实现空的 `IDependency` 标记接口被 Autofac **自动注册**: ```csharp // 在 WIDESEAWCS_Core/IDependency.cs 中 public interface IDependency { } // 您的服务会被自动注册 public class MyService : IDependency // 自动注册为 scoped { // ... } ``` 注册在 `AutofacModuleRegister` 中进行,它会扫描所有项目程序集查找 `IDependency` 实现。 **重要提示**:向 `IServiceCollection` 添加服务时(例如在 `Program.cs` 中),它们可能会被 Autofac 的注册覆盖。使用 `Remove()` 来替换现有注册: ```csharp // 在 RedisServiceSetup.cs 中 - 添加 HybridCacheService 之前移除 MemoryCacheService var existing = services.FirstOrDefault(d => d.ServiceType == typeof(ICacheService)); if (existing != null) services.Remove(existing); ``` ## 缓存 - ICacheService 系统通过 `ICacheService` 使用 **L1(内存)+ L2(Redis)混合缓存**模式。存在三种实现: - `MemoryCacheService` - 仅内存 - `RedisCacheService` - 仅 Redis - `HybridCacheService` - L1+L2 带降级(启用 Redis 时的默认选项) **常用方法**: - `Add/AddObject` - 添加缓存 - `Get/Get` - 获取缓存值 - `Remove` - 删除单个键 - `RemoveByPrefix/RemoveByPattern` - 按模式批量删除 - `GetOrAdd` - 获取或添加(带工厂方法) - `TryAdd/TryUpdate/TryUpdateIfChanged` - ConcurrentDictionary 风格的操作 **配置**(在 `appsettings.json` 中): ```json "RedisConfig": { "Enabled": true, "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,...", "KeyPrefix": "wcs:" } ``` ## Quartz 任务 - 设备通信 任务继承 `JobBase` 并实现 Quartz 的 `IJob`: ```csharp public class MyDeviceJob : JobBase, IJob { public async Task Execute(IJobExecutionContext context) { ExecuteJob(context, async () => { // 任务逻辑 WriteDebug("MyDevice", "调试信息"); WriteInfo("MyDevice", "信息"); }); } } ``` 任务通过 `SchedulerCenterServer` 使用 `Dt_DeviceInfo` 表中的设备信息动态注册。 **设备类型**: - `IStackerCrane` - 堆垛机 - `IConveyorLine` - 输送线 - `IShuttleCar` - 穿梭车 - `IRobot` - 机械手 ## 硬件通信 通信器类封装 `HslCommunication` 库: - `SiemensS7Communicator` / `SiemensS7200SmartCommunicator` - 西门子 PLC - `OmronEtherNetCommunicator` - 欧姆龙 PLC - `ModbusTcpCommunicator` - Modbus TCP - `SerialPortCommunicator` - 串口设备 ## TCP Socket 服务器 `TcpSocketServer`(端口 2000)处理实时设备通信: - 通过 `SocketServerHostedService` 作为 Singleton 管理 - 客户端连接存储在 `ConcurrentDictionary` 中 - 通过 `OnDataReceived` 事件处理消息 ## 机械手通信系统 机械手系统采用模块化架构,包含专门的组件。 **组件**: - `RobotClientManager` - 管理 TCP 客户端连接和订阅 - `RobotStateManager` - 管理机械手状态缓存,支持安全的并发更新 - `RobotMessageHandler` - 处理来自机械手的 TCP 消息 - `RobotTaskProcessor` - 处理任务执行和状态转换 - `RobotBarcodeGenerator` - 生成托盘/条码标识符 **任务类型**(来自 `RobotTaskTypeEnum`): - `GroupPallet (500)` - 组盘任务 - `ChangePallet (510)` - 换盘任务 - `SplitPallet (520)` - 拆盘任务 **状态流转**: 1. 机械手通过 TCP 连接 → ClientManager 跟踪连接 2. 任务轮询获取任务 → TaskProcessor 获取待处理任务 3. 接收消息 → MessageHandler 解析并更新状态 4. 状态转换 → TaskProcessor 向机械手发送命令 ## 通用常量 **通信超时**(`CommunicationConst`): - `WaitIntervalMs: 500` - 设备等待间隔 - `WaitTimeoutBaseMs: 6000` - 超时基数 - `WaitTotalTimeoutMs: 60000` - 总超时时间(10 × 基数) - `PingIntervalMs: 100` - Ping 检测间隔 - `HttpDefaultTimeoutSeconds: 60` - HTTP 超时 **系统集成 URL**(`BaseAPI`): - `WMSBaseUrl: "http://localhost:9291/api/"` - WMS 系统 - `WCSBaseUrl: "http://localhost:9292/api/"` - WCS 系统(本服务器) - `MESBaseUrl: "http://localhost:9293/api/"` - MES 系统 - `ERPBaseUrl: "http://localhost:9294/api/"` - ERP 系统 **Redis 缓存前缀**(`RedisPrefix`): - `System: "System"` - 系统级缓存 - `User: "User"` - 用户特定缓存 - `Code: "Code"` - 代码/配置缓存 使用这些前缀配合 `ICacheService.RemoveByPrefix()` 进行批量缓存失效。 ## 配置设置 `appsettings.json` 中的关键设置: - `"urls": "http://*:9292"` - 服务器端口 - `"QuartzJobAutoStart": true` - 自动启动定时任务 - `"SocketServer:Enabled": true` - 启用 TCP 服务器 - `"RedisConfig:Enabled": true` - 启用 Redis 缓存 - `"LogAOPEnable": false` - 启用 AOP 日志 - `"DBType": "SqlServer"` - 数据库类型 ## 服务层模式 服务遵循分层模式: - **接口**在 `WIDESEAWCS_IService/` 中(例如 `ITaskInfoService`) - **实现**在 `WIDESEAWCS_Service/` 中(例如 `TaskInfoService`) - 两者都实现 `IDependency` 以进行自动注册 ## 基类 - `ServiceBase` - 带有 CRUD 操作的基础服务 - `RepositoryBase` - 基于 SqlSugar ORM 的基础仓储 - `ApiBaseController` - 带有通用功能的基础 API 控制器 - `JobBase` - 带有日志辅助方法的基础 Quartz 任务 ## 添加新功能 1. **新服务**:在 `I*Service/` 中创建接口,在 `*Service/` 中创建类,实现 `IDependency` 2. **新任务**:在 `WIDESEAWCS_Tasks/` 中继承 `JobBase` 和 `IJob` 3. **新设备类型**:在 `WIDESEAWCS_QuartzJob/Device/` 中添加接口并实现 ## 重要说明 - 应用程序使用 **CamelCase** JSON 序列化 - 所有服务默认通过 Autofac 使用 **scoped** 生命周期 - Redis 连接使用 **延迟初始化** - 首次访问时触发连接 - 在任务中使用 `ConsoleHelper.WriteSuccessLine()` / `WriteErrorLine()` 进行控制台输出 - TCP Socket 服务器独立于 HTTP API 运行