| | |
| | | |
| | | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| | | |
| | | ## Build Commands |
| | | ## 项目概述 |
| | | |
| | | **WIDESEAWCS** 是一个仓库控制系统,基于 ASP.NET Core 6.0 构建。用于管理自动化物料处理设备(堆垛机、输送线、机器人、穿梭车等)的工业仓储环境。 |
| | | |
| | | ## 构建与运行命令 |
| | | |
| | | ```bash |
| | | # Build entire solution |
| | | # 构建整个解决方案 |
| | | dotnet build WIDESEAWCS_Server.sln |
| | | |
| | | # Build and run server |
| | | cd WIDESEAWCS_Server |
| | | dotnet run |
| | | # 运行服务器(端口 9292) |
| | | dotnet run --project WIDESEAWCS_Server/WIDESEAWCS_Server.csproj |
| | | |
| | | # Run tests |
| | | cd WIDESEAWCS_Tests |
| | | dotnet test |
| | | # 运行测试 |
| | | dotnet test WIDESEAWCS_Tests/WIDESEAWCS_Tests.csproj |
| | | ``` |
| | | |
| | | ## Architecture Overview |
| | | ## 架构 |
| | | |
| | | This is a **WCS (Warehouse Control System)** built with ASP.NET Core 6.0, using: |
| | | - **Autofac** for DI with automatic service discovery via `IDependency` marker interface |
| | | - **Quartz.NET** for scheduled job execution (device communication loops) |
| | | - **SqlSugar ORM** for database access |
| | | - **Redis** (via `WIDESEAWCS_RedisService`) for distributed caching with L1+L2 hybrid pattern |
| | | - **StackExchange.Redis** for Redis operations |
| | | - **TCP Socket Server** for real-time device communication |
| | | - **HslCommunication** library for PLC/hardware communication |
| | | ### 项目结构 |
| | | |
| | | ## Project Structure |
| | | | 项目 | 用途 | |
| | | | ------------------------- | ----------------------------------- | |
| | | | `WIDESEAWCS_Server` | 主 Web API 入口(端口 9292) | |
| | | | `WIDESEAWCS_Core` | 框架工具(数据库、缓存、依赖注入、日志、认证) | |
| | | | `WIDESEAWCS_Common` | 常量、枚举、Redis 键定义 | |
| | | | `WIDESEAWCS_Model` | 数据库实体模型 | |
| | | | `WIDESEAWCS_DTO` | 数据传输对象 | |
| | | | `WIDESEAWCS_Communicator` | 工业设备通信协议(Modbus、Siemens S7、Omron 等) | |
| | | | `WIDESEAWCS_Tasks` | 后台设备控制作业 | |
| | | | `WIDESEAWCS_QuartzJob` | Quartz.NET 调度和派发逻辑 | |
| | | | `WIDESEAWCS_RedisService` | L1+L2 混合缓存服务 | |
| | | |
| | | ``` |
| | | WIDESEAWCS_Server/ # Main ASP.NET Core API server |
| | | WIDESEAWCS_Core/ # Core infrastructure: base classes, DI, extensions, middleware |
| | | WIDESEAWCS_Model/ # Data models and DTOs |
| | | WIDESEAWCS_Communicator/ # Hardware communication drivers (Siemens, Omron, Modbus, etc.) |
| | | WIDESEAWCS_QuartzJob/ # Job scheduling infrastructure and device abstractions |
| | | WIDESEAWCS_Tasks/ # Quartz job implementations (device communication loops) |
| | | WIDESEAWCS_RedisService/ # Redis services: Cache, Lock, Counter, PubSub, etc. |
| | | WIDESEAWCS_*Repository/ # Data access layer implementations |
| | | WIDESEAWCS_*Service/ # Business service layer |
| | | WIDESEAWCS_Tests/ # Unit tests |
| | | ``` |
| | | ### 关键设计模式 |
| | | |
| | | ## Dependency Injection - IDependency Pattern |
| | | - **仓储模式**:数据访问抽象(`WIDESEAWCS_*Repository` 项目) |
| | | - **服务层**:业务逻辑封装(`WIDESEAWCS_*Service` 项目) |
| | | - **Autofac 依赖注入**:通过 `AutofacModuleRegister` 模块注册 |
| | | - **AOP 拦截**:通过 `UseServiceDIAttribute` 实现缓存和日志切面 |
| | | - **SqlSugar ORM**:支持 MySQL、SQL Server、SQLite、Oracle、PostgreSQL |
| | | |
| | | Services are **automatically registered** with Autofac by implementing the empty `IDependency` marker interface: |
| | | ### 数据流向 |
| | | |
| | | ```csharp |
| | | // In WIDESEAWCS_Core/IDependency.cs |
| | | public interface IDependency { } |
| | | 1. API Controllers → Services → Repositories → SqlSugar → SQL Server |
| | | 2. Quartz Jobs(定时调度) → 设备控制作业 → Communicators → 物理设备 |
| | | 3. Redis L1(内存) + L2(Redis)缓存层位于数据库前方 |
| | | |
| | | // Your service gets auto-registered |
| | | public class MyService : IDependency // Automatically registered as scoped |
| | | { |
| | | // ... |
| | | } |
| | | ``` |
| | | ## 关键配置(appsettings.json) |
| | | |
| | | Registration happens in `AutofacModuleRegister` which scans all project assemblies for `IDependency` implementations. |
| | | - **Web API:** `http://*:9292` |
| | | - **WebSocket:** `http://localhost:9296` |
| | | - **TCP Socket 服务器:** `0.0.0.0:2000` |
| | | - **数据库:** SQL Server,实例 `.\WIDESEAWCS_ShanMei` |
| | | - **Redis:** `127.0.0.1:6379`,密码 `P@ssw0rd` |
| | | - **JWT 过期时间:** 120 分钟 |
| | | - **Quartz:** 自动启动 |
| | | |
| | | **Important**: When adding services to `IServiceCollection` (e.g., in `Program.cs`), they can be overridden by Autofac's registrations. Use `Remove()` to replace existing registrations: |
| | | ## 设备通信 |
| | | |
| | | ```csharp |
| | | // In RedisServiceSetup.cs - removes MemoryCacheService before adding HybridCacheService |
| | | var existing = services.FirstOrDefault(d => d.ServiceType == typeof(ICacheService)); |
| | | if (existing != null) services.Remove(existing); |
| | | ``` |
| | | `WIDESEAWCS_Communicator` 项目实现了多种工业协议: |
| | | |
| | | ## Caching - ICacheService |
| | | - `ModbusTcpCommunicator` |
| | | - `SiemensS7Communicator`、`SiemensS7200SmartCommunicator` |
| | | - `OmronEtherNetCommunicator` |
| | | - `AllenBrandlyEtherNetCommunicator` |
| | | - `InovanceTcpCommunicator`、`InovanceAMTcp` |
| | | - `SerialPortCommunicator` |
| | | |
| | | The system uses a **hybrid L1 (Memory) + L2 (Redis)** cache pattern via `ICacheService`. Three implementations exist: |
| | | - `MemoryCacheService` - Memory only |
| | | - `RedisCacheService` - Redis only |
| | | - `HybridCacheService` - L1+L2 with fallback (default when Redis enabled) |
| | | 基础接口:`IBaseCommunicator` |
| | | |
| | | **Common methods**: |
| | | - `Add/AddObject` - Add cache |
| | | - `Get/Get<T>` - Retrieve cached values |
| | | - `Remove` - Delete single key |
| | | - `RemoveByPrefix/RemoveByPattern` - Bulk delete by pattern |
| | | - `GetOrAdd<T>` - Retrieve or add with factory |
| | | - `TryAdd/TryUpdate/TryUpdateIfChanged` - ConcurrentDictionary-style operations |
| | | ## 后台作业 |
| | | |
| | | **Configuration** in `appsettings.json`: |
| | | ```json |
| | | "RedisConfig": { |
| | | "Enabled": true, |
| | | "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,...", |
| | | "KeyPrefix": "wcs:" |
| | | } |
| | | ``` |
| | | 设备控制作业位于 `WIDESEAWCS_Tasks/`: |
| | | |
| | | ## Quartz Jobs - Device Communication |
| | | - `StackerCraneJob` - 堆垛机控制 |
| | | - `ConveyorLineJob`、`ConveyorLineNewJob` - 输送线管理 |
| | | - `RobotJob` - 机械手控制 |
| | | - `ShuttleCarJob` - 穿梭车控制 |
| | | - `SocketServer` - 设备通信 TCP 服务器 |
| | | |
| | | Jobs inherit from `JobBase` and implement Quartz's `IJob`: |
| | | ## API 结构 |
| | | |
| | | ```csharp |
| | | public class MyDeviceJob : JobBase, IJob |
| | | { |
| | | public async Task Execute(IJobExecutionContext context) |
| | | { |
| | | ExecuteJob(context, async () => { |
| | | // Job logic here |
| | | WriteDebug("MyDevice", "Debug message"); |
| | | WriteInfo("MyDevice", "Info message"); |
| | | }); |
| | | } |
| | | } |
| | | ``` |
| | | - `QuartzJob/Controllers/` - 设备信息、协议、派发、调度器 |
| | | - `System/Controllers/` - 用户、角色、菜单、字典、日志 |
| | | - `Task/Controllers/` - 任务管理和机器人任务 |
| | | - `BasicInfo/Controllers/` - 路由配置 |
| | | |
| | | Jobs are registered dynamically via `SchedulerCenterServer` using device info from `Dt_DeviceInfo` table. |
| | | ## 日志 |
| | | |
| | | **Device types**: |
| | | - `IStackerCrane` - Stacker cranes |
| | | - `IConveyorLine` - Conveyor lines |
| | | - `IShuttleCar` - Shuttle cars |
| | | - `IRobot` - Robot cranes |
| | | 使用 Serilog,按天滚动保留 30 天日志文件,同时集成 Seq(`http://localhost:5341`)。 |
| | | |
| | | ## Hardware Communication |
| | | ## 重要实现注意事项 |
| | | |
| | | Communicator classes wrap the `HslCommunication` library: |
| | | - `SiemensS7Communicator` / `SiemensS7200SmartCommunicator` - Siemens PLCs |
| | | - `OmronEtherNetCommunicator` - Omron PLCs |
| | | - `ModbusTcpCommunicator` - Modbus TCP |
| | | - `SerialPortCommunicator` - Serial port devices |
| | | 1. **启动初始化顺序很重要**:Redis 就绪后才能运行 `ApiRouteCacheWarmupHostedService` |
| | | 2. **Quartz 任务表** 通过 `QuartzJobDataTableHostedService` 在启动时自动创建 |
| | | 3. **Socket 服务器** 作为单例 `TcpSocketServer` 由托管服务运行 |
| | | 4. **Redis 缓存同步**:可配置 `EnableAutoSync` 选项,定期将 Redis 同步到 L1 内存缓存 |
| | | 5. **设备协议配置** 存储在数据库(`Dt_DeviceProtocol` 表),而非配置文件中 |
| | | |
| | | ## TCP Socket Server |
| | | ## 注释与文档 (强制) |
| | | |
| | | The `TcpSocketServer` (port 2000) handles real-time device communication: |
| | | - Managed as a Singleton with `SocketServerHostedService` |
| | | - Client connections stored in `ConcurrentDictionary<string, TcpClient>` |
| | | - Messages handled via `OnDataReceived` event |
| | | - **XML 文档注释**: 所有 `public` 类、接口、方法、属性**必须**包含 XML 文档注释 (`/// <summary>...</summary>`),解释其用途、参数和返回值。 |
| | | - **行内注释**: 对于复杂的业务逻辑、算法实现或非直观的代码块,**必须**添加 `//` 行内注释解释“为什么这么做”。 |
| | | - **TODO 标记**: 如果代码未完成或有临时方案,必须使用 `// TODO: 说明` 标记。 |
| | | |
| | | ## Configuration Settings |
| | | ## 通用规范 |
| | | |
| | | Key settings in `appsettings.json`: |
| | | - `"urls": "http://*:9292"` - Server port |
| | | - `"QuartzJobAutoStart": true` - Auto-start scheduled jobs |
| | | - `"SocketServer:Enabled": true` - Enable TCP server |
| | | - `"RedisConfig:Enabled": true` - Enable Redis caching |
| | | - `"LogAOPEnable": false` - Enable AOP logging |
| | | - `"DBType": "SqlServer"` - Database type |
| | | - **异步编程**: 所有 I/O 操作必须使用 `async/await`。库代码请使用 `ConfigureAwait(false)`。 |
| | | - **命名**: |
| | | - 接口以 "I" 开头 (例如: `IUserService`)。 |
| | | - 类名、方法名使用 **PascalCase**。 |
| | | - 私有字段、局部变量使用 **camelCase**。 |
| | | - **命名空间**: 使用 **文件作用域命名空间** (`namespace MyApp.Api;`)。 |
| | | |
| | | ## Service Layer Pattern |
| | | ## 🚫 严禁事项 |
| | | - **严禁** 生成没有注释的代码 (尤其是公共方法)。 |
| | | - **严禁** 使用 `Task.Result` 或 `Task.Wait()`。 |
| | | - **严禁** 在异步上下文中使用 `.ToList()` (必须用 `.ToListAsync()`)。 |
| | | - **严禁** 直接暴露实体 (Entity),必须使用 DTO。 |
| | | - **严禁** 捕获 `Exception` 而不记录日志。 |
| | | |
| | | Services follow a layered pattern: |
| | | - **Interface** in `WIDESEAWCS_IService/` (e.g., `ITaskInfoService`) |
| | | - **Implementation** in `WIDESEAWCS_Service/` (e.g., `TaskInfoService`) |
| | | - Both implement `IDependency` for auto-registration |
| | | |
| | | ## Base Classes |
| | | |
| | | - `ServiceBase<T, TKey>` - Base service with CRUD operations |
| | | - `RepositoryBase<TEntity>` - Base repository with SqlSugar ORM |
| | | - `ApiBaseController` - Base API controller with common functionality |
| | | - `JobBase` - Base Quartz job with logging helpers |
| | | |
| | | ## Adding New Features |
| | | |
| | | 1. **New Service**: Create interface in `I*Service/` and class in `*Service/`, implement `IDependency` |
| | | 2. **New Job**: Inherit from `JobBase` and `IJob` in `WIDESEAWCS_Tasks/` |
| | | 3. **New Device Type**: Add interface in `WIDESEAWCS_QuartzJob/Device/` and implement |
| | | |
| | | ## Important Notes |
| | | |
| | | - The application uses **CamelCase** JSON serialization |
| | | - All services use **scoped** lifetime by default via Autofac |
| | | - Redis connection uses **Lazy initialization** - first access triggers connection |
| | | - Use `ConsoleHelper.WriteSuccessLine()` / `WriteErrorLine()` for console output in jobs |
| | | - TCP Socket server runs independently of the HTTP API |
| | | ## 🛠 技术栈 |
| | | - **框架**: .NET 8.0 (LTS) |
| | | - **语言**: C# 12 |
| | | - **ORM**: SqlSugar |
| | | - **数据库**: SQL Server |
| | | - **验证**: FluentValidation |
| | | - **序列化**: Newtonsoft.Json |