# 标签模块设计文档 ## 1. 模块概述 标签模块是变色龙系统中的一个核心组件,用于管理和生成各种类型的标签(如STOP标签)。该模块支持根据业务规则自动触发标签生成,并提供标签预览和打印功能。 ### 1.1 设计目标 - 提供统一的标签模板管理能力 - 支持根据业务规则自动触发标签 - 提供标签预览和打印功能 - 确保系统性能高效,响应迅速 - 预留扩展性,便于后续添加缓存机制 ### 1.2 适用场景 - 物流分拣中心的标签管理 - 仓库操作中的标签追踪 - 运输过程中的标签标记 - 异常情况的标签提醒(如STOP标签) ## 2. 系统架构 ### 2.1 架构层次 标签模块采用分层架构设计,与系统其他模块保持一致: ``` ┌─────────────────────┐ │ CONTROLLER层 │ // 控制器层,处理HTTP请求 ├─────────────────────┤ │ BLL层 │ // 业务逻辑层,实现核心业务逻辑 ├─────────────────────┤ │ DAL层 │ // 数据访问层,处理数据库操作 ├─────────────────────┤ │ MDL层 │ // 数据模型层,定义数据结构 └─────────────────────┘ ``` ### 2.2 核心组件 | 组件名称 | 所在文件 | 功能描述 | |---------|---------|----------| | TagTemplateEntity | MDL/Models/TagTemplateEntity.cs | 标签模板实体模型 | | TagInstanceEntity | MDL/Models/TagInstanceEntity.cs | 标签实例实体模型 | | ITagRepository | DAL/Interfaces/ITagRepository.cs | 标签数据访问接口 | | TagRepository | DAL/Repositories/TagRepository.cs | 标签数据访问实现 | | ITagService | BLL/Interfaces/ITagService.cs | 标签业务逻辑接口 | | TagService | BLL/Services/TagService.cs | 标签业务逻辑实现 | | TagController | CONTROLLER/Controllers/TagController.cs | 标签API控制器 | | ITagRenderer | BLL/Interfaces/ITagRenderer.cs | 标签渲染接口 | | HtmlTagRenderer | BLL/Services/HtmlTagRenderer.cs | HTML标签渲染实现 | | ZplTagRenderer | BLL/Services/ZplTagRenderer.cs | ZPL标签渲染实现 | | ICacheService | BLL/Interfaces/ICacheService.cs | 缓存服务接口(预留) | | NoCacheService | BLL/Services/NoCacheService.cs | 无缓存实现(当前使用) | | RedisCacheService | BLL/Services/RedisCacheService.cs | Redis缓存实现(预留) | ## 3. 数据模型设计 ### 3.1 标签模板实体(TagTemplateEntity) | 字段名称 | 数据类型 | 长度 | 约束 | 描述 | |---------|---------|------|------|------| | Id | int | - | 主键,自增 | 模板ID | | TagType | string | 50 | 非空,唯一 | 标签类型(如STOP、暂存) | | Name | string | 100 | 非空 | 标签名称 | | TemplateConfig | string | - | 非空 | 模板配置(JSON格式) | | TriggerRule | string | - | 非空 | 触发规则(JSON格式) | | IsActive | bool | - | 默认true | 是否启用 | | CreatedAt | DateTime | - | 默认当前时间 | 创建时间 | | UpdatedAt | DateTime | - | 默认当前时间 | 更新时间 | ### 3.2 标签实例实体(TagInstanceEntity) | 字段名称 | 数据类型 | 长度 | 约束 | 描述 | |---------|---------|------|------|------| | Id | long | - | 主键,自增 | 实例ID | | TagType | string | 50 | 非空 | 标签类型 | | TemplateId | int | - | 非空 | 模板ID | | NeutralWaybillNumber | string | 100 | 非空 | 中性单号 | | CustomerId | int | - | 非空 | 客户编码 | | Status | string | 20 | 默认"ACTIVE" | 状态(ACTIVE/INACTIVE) | | TriggerTime | DateTime | - | 非空 | 触发时间 | | CreatedAt | DateTime | - | 默认当前时间 | 创建时间 | | UpdatedAt | DateTime | - | 默认当前时间 | 更新时间 | ### 3.3 请求模型(TagRequest) | 模型名称 | 字段名称 | 数据类型 | 描述 | |---------|---------|---------|------| | CreateTagTemplateRequest | TagType | string | 标签类型 | | CreateTagTemplateRequest | Name | string | 标签名称 | | CreateTagTemplateRequest | TemplateConfig | string | 模板配置(JSON格式) | | CreateTagTemplateRequest | TriggerRule | string | 触发规则(JSON格式) | | CheckTriggerRequest | NeutralWaybillNumber | string | 中性单号 | | CheckTriggerRequest | CustomerId | int | 客户编码 | | CheckTriggerRequest | TagTypes | List | 标签类型列表 | | GenerateTagRequest | TagType | string | 标签类型 | | GenerateTagRequest | NeutralWaybillNumber | string | 中性单号 | | GenerateTagRequest | CustomerId | int | 客户编码 | | RenderTagRequest | TemplateId | int | 模板ID | | RenderTagRequest | Data | Dictionary | 标签数据 | ## 4. 业务逻辑设计 ### 4.1 标签模板管理 - **功能**:管理标签模板的创建、更新、删除和查询 - **流程**: 1. 接收模板管理请求 2. 验证请求参数 3. 执行相应的CRUD操作 4. 返回操作结果 ### 4.2 STOP标签触发逻辑 - **功能**:根据业务规则自动触发STOP标签 - **流程**: 1. 接收触发检查请求(中性单号、客户编码) 2. 查询第一次扫描时间T(从label_scan_history表) 3. 计算T+5截止时间(5天后的23:59:59) 4. 检查是否超过截止时间 5. 检查是否有尾程标签(FinalMileTrackingNumber不为空) 6. 若满足条件,触发STOP标签生成 ### 4.3 标签生成 - **功能**:生成标签实例 - **流程**: 1. 接收标签生成请求 2. 检查是否已存在同类型激活标签 3. 获取标签模板 4. 创建标签实例 5. 保存到数据库 6. 返回生成结果 ### 4.4 标签渲染 - **功能**:将标签模板渲染为HTML(预览)或ZPL(打印) - **流程**: 1. 接收渲染请求 2. 获取标签模板 3. 解析模板配置 4. 替换模板变量 5. 渲染为目标格式 6. 返回渲染结果 ## 5. 数据库设计 ### 5.1 标签模板表(tag_templates) ```sql CREATE TABLE IF NOT EXISTS `tag_templates` ( `Id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '模板ID', `TagType` VARCHAR(50) NOT NULL COMMENT '标签类型', `Name` VARCHAR(100) NOT NULL COMMENT '标签名称', `TemplateConfig` TEXT NOT NULL COMMENT '模板配置(JSON格式)', `TriggerRule` TEXT NOT NULL COMMENT '触发规则(JSON格式)', `IsActive` TINYINT(1) DEFAULT 1 COMMENT '是否启用', `CreatedAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdatedAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`Id`), UNIQUE KEY `UK_TagType` (`TagType`), KEY `IX_IsActive` (`IsActive`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='标签模板表'; ``` ### 5.2 标签实例表(tag_instances) ```sql CREATE TABLE IF NOT EXISTS `tag_instances` ( `Id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '实例ID', `TagType` VARCHAR(50) NOT NULL COMMENT '标签类型', `TemplateId` INT(11) NOT NULL COMMENT '模板ID', `NeutralWaybillNumber` VARCHAR(100) NOT NULL COMMENT '中性单号', `CustomerId` INT(11) NOT NULL COMMENT '客户编码', `Status` VARCHAR(20) DEFAULT 'ACTIVE' COMMENT '状态(ACTIVE/INACTIVE)', `TriggerTime` DATETIME NOT NULL COMMENT '触发时间', `CreatedAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdatedAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`Id`), KEY `IX_NeutralWaybillNumber` (`NeutralWaybillNumber`), KEY `IX_CustomerId` (`CustomerId`), KEY `IX_TagType` (`TagType`), KEY `IX_Status` (`Status`), CONSTRAINT `FK_TagInstances_TagTemplates` FOREIGN KEY (`TemplateId`) REFERENCES `tag_templates` (`Id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='标签实例表'; ``` ## 6. 实现细节 ### 6.1 技术栈 - 语言:C# - 框架:ASP.NET Core - 数据库:MySQL - ORM:SqlSugar - 依赖注入:Microsoft.Extensions.DependencyInjection ### 6.2 核心实现 #### 6.2.1 缓存服务接口(预留扩展性) ```csharp public interface ICacheService { Task GetStringAsync(string key); Task SetStringAsync(string key, string value, TimeSpan? expiration = null); Task RemoveAsync(string key); } ``` #### 6.2.2 无缓存实现 ```csharp public class NoCacheService : ICacheService { public Task GetStringAsync(string key) { return Task.FromResult(null); } public Task SetStringAsync(string key, string value, TimeSpan? expiration = null) { return Task.CompletedTask; } public Task RemoveAsync(string key) { return Task.CompletedTask; } } ``` #### 6.2.3 STOP标签触发逻辑 ```csharp public async Task CheckStopTagTriggerAsync(string neutralWaybillNumber, int customerId) { // 1. 查询第一次扫描时间T var firstScan = await _scanRepository.GetFirstScanAsync(neutralWaybillNumber, customerId); if (firstScan == null) { return false; } // 2. 计算T+5截止时间 var tPlus5 = firstScan.CreatedAt.AddDays(5).Date.AddHours(23).AddMinutes(59).AddSeconds(59); // 3. 检查是否超过截止时间 if (DateTime.Now <= tPlus5) { return false; } // 4. 检查是否有尾程标签 var hasLastMileTag = await _scanRepository.HasLastMileTrackingAsync(neutralWaybillNumber, customerId); return !hasLastMileTag; } ``` #### 6.2.4 标签渲染逻辑 ```csharp public async Task RenderHtmlAsync(int templateId, Dictionary data) { var template = await _tagRepository.GetTemplateByIdAsync(templateId); if (template == null) { throw new Exception("Template not found"); } var config = JsonSerializer.Deserialize(template.TemplateConfig); var html = new StringBuilder(); // 生成HTML结构 html.AppendLine($"
"); foreach (var element in config.Elements) { if (element.Type == "text") { var content = ReplaceVariables(element.Content, data); html.AppendLine($"
{content}
"); } else if (element.Type == "barcode") { var content = ReplaceVariables(element.Content, data); // 生成条形码的HTML表示 html.AppendLine($"
"); html.AppendLine($""); html.AppendLine($"
"); } } html.AppendLine($"
"); return html.ToString(); } ``` ### 6.3 依赖注入配置 ```csharp builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // 当前使用无缓存实现 // 后续可切换为Redis缓存实现: // builder.Services.AddScoped(); ``` ## 7. 扩展性设计 ### 7.1 缓存扩展 - 预留了ICacheService接口,可无缝切换为RedisCacheService - 所有缓存操作通过接口调用,实现与具体缓存实现解耦 ### 7.2 标签类型扩展 - 采用模板化设计,支持添加新的标签类型 - 触发规则通过JSON配置,可灵活定义 ### 7.3 渲染格式扩展 - 预留了ITagRenderer接口,可添加新的渲染格式(如PDF) - 渲染逻辑与业务逻辑解耦,便于扩展 ### 7.4 API扩展 - 采用RESTful API设计,支持版本控制 - 接口设计遵循REST原则,便于扩展新功能 ## 8. 代码结构 ``` src/ ├── MDL/ │ └── Models/ │ ├── TagTemplateEntity.cs // 标签模板实体 │ ├── TagInstanceEntity.cs // 标签实例实体 │ └── TagRequest.cs // 标签相关请求模型 ├── DAL/ │ ├── Interfaces/ │ │ ├── ITagRepository.cs // 标签数据访问接口 │ │ └── IScanRepository.cs // 扫描记录数据访问接口 │ └── Repositories/ │ ├── TagRepository.cs // 标签数据访问实现 │ └── ScanRepository.cs // 扫描记录数据访问实现 ├── BLL/ │ ├── Interfaces/ │ │ ├── ITagService.cs // 标签业务逻辑接口 │ │ ├── ITagRenderer.cs // 标签渲染接口 │ │ └── ICacheService.cs // 缓存服务接口 │ └── Services/ │ ├── TagService.cs // 标签业务逻辑实现 │ ├── HtmlTagRenderer.cs // HTML标签渲染实现 │ ├── ZplTagRenderer.cs // ZPL标签渲染实现 │ ├── NoCacheService.cs // 无缓存实现 │ └── RedisCacheService.cs // Redis缓存实现(预留) └── CONTROLLER/ └── Controllers/ └── TagController.cs // 标签API控制器 ``` ## 9. 性能优化 ### 9.1 数据库优化 - 为关键表添加索引,加速查询 - 使用合适的数据类型,减少存储空间 - 优化SQL查询,避免全表扫描 ### 9.2 代码优化 - 使用异步编程,提高并发性能 - 减少数据库查询次数,采用批量操作 - 优化时间计算逻辑,减少CPU开销 ### 9.3 内存优化 - 合理使用对象池,减少GC压力 - 避免内存泄漏,及时释放资源 - 优化大对象处理,减少内存占用 ## 10. 总结 标签模块通过分层架构设计,实现了标签的全生命周期管理和自动触发功能。该模块预留了扩展性,便于后续添加缓存机制和其他功能扩展。同时,通过性能优化措施,确保系统响应迅速,满足业务需求。 - **数据一致性**:与系统其他模块保持一致的命名规范和数据结构 - **业务完整性**:实现了标签从模板管理到生成、渲染的完整流程 - **系统集成性**:与扫描记录系统无缝集成,实现自动触发 - **可扩展性**:预留了缓存接口和其他扩展点,便于后续功能扩展 标签模块的实现为变色龙系统中的标签管理提供了一个可靠、高效的解决方案,支持各种业务场景的需求。