wanshenmean
7 天以前 fd18eaba5e1c086a588509371f91310e7aafff9c
Code/WCS/WIDESEAWCS_Server/CLAUDE.md
@@ -2,221 +2,131 @@
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: 说明` 标记。
## Robot Communication System
## 通用规范
The robot crane system uses a modular architecture with specialized components.
- **异步编程**: 所有 I/O 操作必须使用 `async/await`。库代码请使用 `ConfigureAwait(false)`。
- **命名**:
  - 接口以 "I" 开头 (例如: `IUserService`)。
  - 类名、方法名使用 **PascalCase**。
  - 私有字段、局部变量使用 **camelCase**。
- **命名空间**: 使用 **文件作用域命名空间** (`namespace MyApp.Api;`)。
**Components:**
## 🚫 严禁事项
- **严禁** 生成没有注释的代码 (尤其是公共方法)。
- **严禁** 使用 `Task.Result` 或 `Task.Wait()`。
- **严禁** 在异步上下文中使用 `.ToList()` (必须用 `.ToListAsync()`)。
- **严禁** 直接暴露实体 (Entity),必须使用 DTO。
- **严禁** 捕获 `Exception` 而不记录日志。
- `RobotClientManager` - Manages TCP client connections and subscriptions
- `RobotStateManager` - Manages robot state cache with safe concurrent updates
- `RobotMessageHandler` - Processes incoming TCP messages from robots
- `RobotTaskProcessor` - Handles task execution and state transitions
- `RobotBarcodeGenerator` - Generates tray/barcode identifiers
**Task Types** (from `RobotTaskTypeEnum`):
- `GroupPallet (500)` - 组盘任务
- `ChangePallet (510)` - 换盘任务
- `SplitPallet (520)` - 拆盘任务
**State Flow:**
1. Robot connects via TCP → ClientManager tracks connection
2. Job polls for tasks → TaskProcessor gets pending tasks
3. Message received → MessageHandler parses and updates state
4. State transitions → TaskProcessor sends commands back to robot
## Common Constants
**Communication Timeouts** (`CommunicationConst`):
- `WaitIntervalMs: 500` - Device wait interval
- `WaitTimeoutBaseMs: 6000` - Timeout base
- `WaitTotalTimeoutMs: 60000` - Total timeout (10 × base)
- `PingIntervalMs: 100` - Ping check interval
- `HttpDefaultTimeoutSeconds: 60` - HTTP timeout
**System Integration URLs** (`BaseAPI`):
- `WMSBaseUrl: "http://localhost:9291/api/"` - WMS system
- `WCSBaseUrl: "http://localhost:9292/api/"` - WCS system (this server)
- `MESBaseUrl: "http://localhost:9293/api/"` - MES system
- `ERPBaseUrl: "http://localhost:9294/api/"` - ERP system
**Redis Cache Prefixes** (`RedisPrefix`):
- `System: "System"` - System-level cache
- `User: "User"` - User-specific cache
- `Code: "Code"` - Code/configuration cache
Use these prefixes with `ICacheService.RemoveByPrefix()` for bulk cache invalidation.
## 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
## Service Layer Pattern
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