编辑 | blame | 历史 | 原始文档

CLAUDE.md

本文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。

构建命令

# 构建整个解决方案
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 自动注册

// 在 WIDESEAWCS_Core/IDependency.cs 中
public interface IDependency { }

// 您的服务会被自动注册
public class MyService : IDependency  // 自动注册为 scoped
{
    // ...
}

注册在 AutofacModuleRegister 中进行,它会扫描所有项目程序集查找 IDependency 实现。

重要提示:向 IServiceCollection 添加服务时(例如在 Program.cs 中),它们可能会被 Autofac 的注册覆盖。使用 Remove() 来替换现有注册:

// 在 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<T> - 获取缓存值
  • Remove - 删除单个键
  • RemoveByPrefix/RemoveByPattern - 按模式批量删除
  • GetOrAdd<T> - 获取或添加(带工厂方法)
  • TryAdd/TryUpdate/TryUpdateIfChanged - ConcurrentDictionary 风格的操作

配置(在 appsettings.json 中):

"RedisConfig": {
  "Enabled": true,
  "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,...",
  "KeyPrefix": "wcs:"
}

Quartz 任务 - 设备通信

任务继承 JobBase 并实现 Quartz 的 IJob

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<string, TcpClient>
  • 通过 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 超时

系统集成 URLBaseAPI):

  • 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<T, TKey> - 带有 CRUD 操作的基础服务
  • RepositoryBase<TEntity> - 基于 SqlSugar ORM 的基础仓储
  • ApiBaseController - 带有通用功能的基础 API 控制器
  • JobBase - 带有日志辅助方法的基础 Quartz 任务

添加新功能

  1. 新服务:在 I*Service/ 中创建接口,在 *Service/ 中创建类,实现 IDependency
  2. 新任务:在 WIDESEAWCS_Tasks/ 中继承 JobBaseIJob
  3. 新设备类型:在 WIDESEAWCS_QuartzJob/Device/ 中添加接口并实现

重要说明

  • 应用程序使用 CamelCase JSON 序列化
  • 所有服务默认通过 Autofac 使用 scoped 生命周期
  • Redis 连接使用 延迟初始化 - 首次访问时触发连接
  • 在任务中使用 ConsoleHelper.WriteSuccessLine() / WriteErrorLine() 进行控制台输出
  • TCP Socket 服务器独立于 HTTP API 运行

代码风格与命名规范

  • 语言:C#,各项目已启用可空引用(nullable)。
  • 缩进:4 个空格;大括号换行(与现有代码保持一致)。
  • 命名:类型/方法/属性使用 PascalCase,局部变量/参数使用 camelCase,接口以 I 前缀命名。
  • 文件命名与类型名保持一致(例如 Sys_UserService.csTaskController.cs)。
  • .editorconfig 当前对 *.cs 抑制 CS8618;未经团队确认不要新增大范围警告抑制。
  • 为新生成或者修改的代码的每一行添加详细注释,包括:
  • 方法的目的说明
  • 参数说明
  • 返回值说明
  • 每一行代码的作用
  • 异常情况的说明