上传源代码版本
This commit is contained in:
397
标签模块设计文档.md
Normal file
397
标签模块设计文档.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# 标签模块设计文档
|
||||
|
||||
## 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
|
||||
- ORM:SqlSugar
|
||||
- 依赖注入: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. 总结
|
||||
|
||||
标签模块通过分层架构设计,实现了标签的全生命周期管理和自动触发功能。该模块预留了扩展性,便于后续添加缓存机制和其他功能扩展。同时,通过性能优化措施,确保系统响应迅速,满足业务需求。
|
||||
|
||||
- **数据一致性**:与系统其他模块保持一致的命名规范和数据结构
|
||||
- **业务完整性**:实现了标签从模板管理到生成、渲染的完整流程
|
||||
- **系统集成性**:与扫描记录系统无缝集成,实现自动触发
|
||||
- **可扩展性**:预留了缓存接口和其他扩展点,便于后续功能扩展
|
||||
|
||||
标签模块的实现为变色龙系统中的标签管理提供了一个可靠、高效的解决方案,支持各种业务场景的需求。
|
||||
Reference in New Issue
Block a user