C# Winform通用开发框架,支持多语言,多数据库,自动更新,模块化,可用其开发任意CS端系统,非常适合需要快速搭建项目的团队或个人使用。

——立足功能、贯通流程、面向二次开发

一、模块定位

标签管理(LabelManage)是 LCIT.CPS 制造执行系统「配置中心」子系统下的核心业务单元,负责

  1. 标签参数(LabelParameter)的统一定义;
  2. 标签模板(LabelTemplate)的可视化设计;
  3. 模板与参数的动态绑定(LabelTemplate2Param);
  4. 标签打印驱动的统一封装与调试。

通过「参数-模板-打印」三层模型,将现场标签格式变化转化为可配置数据,实现零编码新增或修改标签。

二、整体架构

┌─────────────── 标签管理(LabelManage) ───────────────┐
│ UI 层(FrmLabel*) │ 业务层(BLL) │ 实体层(Entity) │ 数据层(Repository) │ 驱动层(Label) │
└──────────────────────────────────────────────────────────┘
项目 命名空间 关键类 职责
UI 层 LCIT.CPS.Client.Applications.Configuration.LabelManage FrmLabelParameter/FrmLabelTemplate... 收集用户输入、调用 BLL、渲染结果
BLL 层 LCIT.CPS.BLL.Configuration.LabelManage LabelParameterBLL / LabelTemplateBLL 事务编排、DTO 转换、权限校验
Entity LCIT.CPS.Entity.Configuration.LabelManage LabelParameter / LabelTemplate / LabelTemplate2Param 纯 POCO,与表结构一一对应
Repository LCIT.CPS.Repository RepositoryFactory 通用 CRUD、分页、事务、原始 SQL 支持
驱动层 LCIT.CPS.Label PrintHelper / LCtrlPanelDrop 与物理打印机交互、模板序列化、画布拖拽设计

注:红色项目为日常二次开发高频改动点(见开发文档),本文重点覆盖。

三、数据模型

3.1 表结构关系

CFG_LabelParameter   (Id, ParameterCode, ParameterName, Remark, ...)
CFG_LabelTemplate    (Id, TemplateCode, TemplateName, BarcodeType, TemplatePath, LabelContent, ...)
CFG_LabelTemplate2Param (Id, TemplateId, ParameterId)
  • 一对多:Template 1-N Template2Param N-1 Parameter
  • LabelContent 字段存储 JSON 格式的「打印内容描述」,由驱动层反序列化为 LabelPrintContent 对象。

3.2 关键 DTO

public class LabelParameterDto : BaseEntity<long>, IMayHaveTenant { ... }
public class LabelTemplateDto : BaseEntity<long>, IMayHaveTenant { ... }
public class LabelTemplate2ParamDto : BaseEntity<long>, IMayHaveTenant { ... }

所有 DTO 通过 AutoMapper 与 Entity 互转,避免手工编码。

四、功能点与交互流程

4.1 标签参数维护(FrmLabelParameter)

4.1.1 列表 & 分页
  • 入口:配置中心 → 标签参数
  • 加载:_labelParamBLL.GetTableOnPage(whereSql, pageIndex, pageSize)
  • 特性:支持参数代码/名称模糊查询、分页、勾选批量删除、双击编辑。
4.1.2 新增 / 编辑(FrmLabelParameterDetail)
  1. 输入校验(ValidateRequired)→ 必填:ParameterCode、ParameterName
  2. 若 Id=0 调用 CreateEntityAsync;否则 UpdateEntityAsync,同时写入 LastModificationTime、LastModifierUserId
  3. 回调事件 CallBackEvent → 刷新父列表。

4.2 标签模板维护(FrmLabelTemplate)

4.2.1 列表 & 分页

同参数列表,whereSql 支持 TemplateCode、TemplateName。

4.2.2 模板设计(FrmLabelTemplateDesign)
  • 画布:LCtrlPanelDrop 封装拖拽、缩放、对齐、属性网格。
  • 数据绑定:将左侧「已绑定参数」拖入画布,自动生成 LabelPrintParam。
  • 序列化:点击保存 → LabelPrintContent 转 JSON → 写回 CFG_LabelTemplate.LabelContent。
  • 反序列化:打开设计器时自动加载历史内容,恢复画布。
4.2.3 模板与参数绑定(FrmLabelTemplate2Param)
  1. 左侧列表显示所有参数;右侧已勾选当前模板已绑定的参数。
  2. 勾选/取消后,一次性提交:
await _labelTempBLL.CreateLabelTemp2ParamAsync(templateId, selectedParamIds);

内部先 Delete 旧关系 → 循环 Insert 新关系,事务保护。

4.3 打印测试(FrmLabelPrintTest)

  1. 下拉框加载系统已安装打印机(PrinterHelper.GetInstalledPrinter)。
  2. 选择模板 → 后台取得模板关联参数 → 构造 LabelPrintParam 列表。
  3. 输入「打印内容」→ 作为所有参数的默认值。
  4. PrintHelper 负责:
  • 反序列化 LabelContent;
  • 按参数名替换占位符;
  • 调用底层驱动(支持 Windows Driver / 串口 / TCP 斑马)。
  1. 打印结果回写日志表(可选扩展)。

五、关键代码解读

5.1 事务级联保存(LabelTemplateBLL)

public async Task CreateLabelTemp2ParamAsync(long tempId, List<string> list_ParamIds)
{
    using (var dbTransaction = Db.BeginTrans())
    {
        Db.Delete<LabelTemplate2Param>("TemplateId", tempId.ToString(), dbTransaction);
        ...
        Db.Commit();
    }
}
  • 显式开启事务,确保「先清后插」原子性;
  • 任意失败即 Rollback,抛出到 UI 层统一提示。

5.2 参数去重校验(CheckIsExist)

public async Task<bool> CheckIsExist(long templateId, long parameterId)
{
    var whereSQL = $"And TemplateId='{templateId}' And ParameterId='{parameterId}'";
    var count = await Db.GetCountAsync<LabelTemplate2Param>(whereSQL);
    return count > 0;
}

用于绑定页勾选时实时提示「已绑定」,避免重复提交。

5.3 打印内容对象(LabelPrintContent)

{
  "PaperWidth": 100,
  "PaperHeight": 60,
  "Items": [
    {
      "Type": "Text",
      "Left": 10,
      "Top": 10,
      "Width": 80,
      "Height": 20,
      "Font": "Arial,12",
      "Text": "{ParameterCode}"
    },
    {
      "Type": "Barcode",
      "Symbology": "Code128",
      "Left": 10,
      "Top": 35,
      "Width": 80,
      "Height": 20,
      "Text": "{ParameterCode}"
    }
  ]
}
  • {} 内字符串与 LabelParameter.ParameterCode 完全一致,PrintHelper 用反射替换;
  • 新增条码类型只需在数据字典 BarcodeType 中维护,无需改代码。

六、扩展点指南

需求场景 应改动点 说明
新增字段(如环保标识) CFG_LabelParameter、LabelParameterDto、FrmLabelParameterDetail 遵循「数据库→Entity→DTO→UI」四连改
支持二维码 数据字典 BarcodeType 新增 QRCode;驱动层 LabelPrintContent 新增 QrCode 类型 UI 无需改动
多语言 所有 Text 改为多语言 Key,调用 L("Key") CPS 框架已内置 ILocalizationService
多租户 所有表/实体已实现 IMayHaveTenant,BLL 自动过滤 TenantId 只需在登录时注入 CurrentTenantId

七、常见故障排查

现象 可能原因 快速定位
模板设计器打不开 LabelContent JSON 被手动篡改 数据库置空该字段,重新设计
打印空白 参数名大小写不一致 检查打印日志,确认 {ParameterCode} 与实际代码完全一致
绑定参数保存失败 事务内异常 查看 LogHelper 写入的 Error 目录,确认唯一索引冲突

八、结语

标签管理模块通过「参数-模板-打印」模型,把传统硬编码的标签格式彻底数据化。二次开发时,90% 需求只需修改配置或增加字典项,真正需要编码的场景集中在驱动层新打印机适配。理解上述流程与代码骨架后,可在 1-2 小时内完成新标签上线,显著降低交付成本。

C# Winform通用开发框架,支持多语言,多数据库,自动更新,模块化,可用其开发任意CS端系统,非常适合需要快速搭建项目的团队或个人使用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐