Files
LabelChange-server/标签模块设计文档.md
2026-06-01 16:30:29 +08:00

397 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 标签模块设计文档
## 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<string> | 标签类型列表 |
| GenerateTagRequest | TagType | string | 标签类型 |
| GenerateTagRequest | NeutralWaybillNumber | string | 中性单号 |
| GenerateTagRequest | CustomerId | int | 客户编码 |
| RenderTagRequest | TemplateId | int | 模板ID |
| RenderTagRequest | Data | Dictionary<string, object> | 标签数据 |
## 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
- ORMSqlSugar
- 依赖注入Microsoft.Extensions.DependencyInjection
### 6.2 核心实现
#### 6.2.1 缓存服务接口(预留扩展性)
```csharp
public interface ICacheService
{
Task<string> 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<string> GetStringAsync(string key)
{
return Task.FromResult<string>(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<bool> 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<string> RenderHtmlAsync(int templateId, Dictionary<string, object> data)
{
var template = await _tagRepository.GetTemplateByIdAsync(templateId);
if (template == null)
{
throw new Exception("Template not found");
}
var config = JsonSerializer.Deserialize<TagTemplateConfig>(template.TemplateConfig);
var html = new StringBuilder();
// 生成HTML结构
html.AppendLine($"<div style='width:{config.Width}in; height:{config.Height}in; border:1px solid black; padding:0.25in;'>");
foreach (var element in config.Elements)
{
if (element.Type == "text")
{
var content = ReplaceVariables(element.Content, data);
html.AppendLine($"<div style='position:absolute; left:{element.X}in; top:{element.Y}in; font-size:{element.FontSize}pt; {(element.Bold ? "font-weight:bold;" : "")}'>{content}</div>");
}
else if (element.Type == "barcode")
{
var content = ReplaceVariables(element.Content, data);
// 生成条形码的HTML表示
html.AppendLine($"<div style='position:absolute; left:{element.X}in; top:{element.Y}in; width:{element.Width}in; height:{element.Height}in;'>");
html.AppendLine($"<img src='data:image/png;base64,{GenerateBarcode(content)}' style='width:100%; height:100%;' />");
html.AppendLine($"</div>");
}
}
html.AppendLine($"</div>");
return html.ToString();
}
```
### 6.3 依赖注入配置
```csharp
builder.Services.AddScoped<ITagRepository, TagRepository>();
builder.Services.AddScoped<ITagService, TagService>();
builder.Services.AddScoped<IScanRepository, ScanRepository>();
builder.Services.AddScoped<ITagRenderer, HtmlTagRenderer>();
builder.Services.AddScoped<ITagRenderer, ZplTagRenderer>();
builder.Services.AddScoped<ICacheService, NoCacheService>(); // 当前使用无缓存实现
// 后续可切换为Redis缓存实现
// builder.Services.AddScoped<ICacheService, RedisCacheService>();
```
## 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. 总结
标签模块通过分层架构设计,实现了标签的全生命周期管理和自动触发功能。该模块预留了扩展性,便于后续添加缓存机制和其他功能扩展。同时,通过性能优化措施,确保系统响应迅速,满足业务需求。
- **数据一致性**:与系统其他模块保持一致的命名规范和数据结构
- **业务完整性**:实现了标签从模板管理到生成、渲染的完整流程
- **系统集成性**:与扫描记录系统无缝集成,实现自动触发
- **可扩展性**:预留了缓存接口和其他扩展点,便于后续功能扩展
标签模块的实现为变色龙系统中的标签管理提供了一个可靠、高效的解决方案,支持各种业务场景的需求。