WinForm应用实战开发指南 - 如何实现通用业务编码规则生成?
在我们很多应用系统中往往都需要根据实际情况生成一些编码规则如订单号、入库单号、出库单号、退货单号等。有时候根据规则自行增加一个函数来生成处理不过仔细观察后发现它们的编码规则有很大的共通性因此可以考虑使用一些通用的业务编码规则生成从而在系统中统一维护即可本文将介绍如何在WinForm界面中实现通用的业务编码规则生成。PS给大家推荐一个C#开发可以用到的界面组件——DevExpress WinForms它能完美构建流畅、美观且易于使用的应用程序无论是Office风格的界面还是分析处理大批量的业务数据它都能轻松胜任DevExpress新旧版本帮助文档获取可点击这篇文章查看——《界面控件DevExpress v26.1帮助文档大全CHM版本》一、常见单号的业务编码规则刚才我们提到一些编码规则如订单号、入库单号、出库单号、退货单号等等它们都是有大同小异的规则有前缀、有日期的编码、有一些流水号还有一些特殊的规则处理往往就是这些需要协调好流水号的增加处理即可。例如原来在我的CRM业务模块中增加了一个函数用来生成订单号的如下所示。/// summary /// 生成单据号码,编码为XS-{userId}-{yyyyMMdd}-流水号 /// /summary /// returns/returns public async Taskstring GetOrderNo() { string prefix string.Format(XS-{0}-{1}, CurrentApiUser.Id, DateTime.Now.ToString(yyyyMMdd)); //获取当天的记录数量1 DateTime currentDate DateTime.Now.ToString(yyyy-MM-dd).ToDateTime(); //当前日期 //计算条件数量1 int count this.EntityDb.Count(s s.OrderDate currentDate s.OrderDate currentDate.AddDays(1)) 1; //循环检索直到不重复的编号 string number string.Format({0}-{1}, prefix, count); while (true) { var result await CheckNumberExist(number); if (result) { //存在增加1再判断 number string.Format({0}-{1}, prefix, count); } else { break; } } return number; }这里为了增加对流水号的循环判断直到没有重复的即可输出来作为订单号。大多数的编码规则大同小异因此我们可以考虑使用共同的规则进行处理类似通用字典的模块处理。订单编码可以在新建订单的时候生成也可以提供用户手动生成【生成编号】的操作如下界面所示。二、设计通用的业务编码规则我们归纳了一些编码规则基本上也就是前缀日期分隔分隔符后缀流水号这些元素的组合如果需要更加复杂的也可以自行调整接口这里设计一个通用的编码规则对这些元素进行组合配置数据库设计如下所示。根据这些内容使用手工编码或者代码生成工具生成相关的基础代码 可以基于EnterpriseLibrary的框架代码或者基于SqlSugar开发框架的代码最终我们都用于WinForm的界面调用。这里以基于SqlSugar开发框架的代码生成为例。生成后会生成一个相关的业务类实现相关的CRUD接口如下代码定义所示如果你有自己的基础框架实现那么也可以忽略具体的代码生成关注业务编码的生成的的规则即可。/// summary /// 业务表编码规则 应用层服务接口实现 /// /summary public class TableNumberService : MyCrudServiceTableNumberInfo, string, TableNumberPagedDto, ITableNumberService为了控制编码的规则生成我们增加一个同步锁来实现冲突处理。/// summary /// 同步锁 /// /summary private static SemaphoreSlim syncRoot new SemaphoreSlim(1);最终我们的实现代码如下所示。/// summary /// 根据定义表名、单据头、分割符1、分割符2生成业务编码。如果生成错误返回空字符串 /// /summary /// param nametableNameOrCode表名或代码/param /// returns/returns public async Taskstring GenerateNumber(string tableNameOrCode) { string businessNumber ; await syncRoot.WaitAsync(); //等待锁 try { var info await base.GetFirstAsync(s s.TableName tableNameOrCode || s.Code tableNameOrCode); if (info ! null) { string currentDate ; string lastDate ; int currentNumber 1; //流水号起始值 int serialLength 3; //流水号长度 if(!info.LastGenerateTime.HasValue) { info.LastGenerateTime DateTime.Now; } if (info.RuleFormat 年月日) { currentDate DateTime.Now.ToString(yyyyMMdd); lastDate info.LastGenerateTime.Value.ToString(yyyyMMdd); } else if (info.RuleFormat 年月) { currentDate DateTime.Now.ToString(yyyyMM); lastDate info.LastGenerateTime.Value.ToString(yyyyMM); } //如果当前日期和最后日期不一致流水号重置为0 if(!currentDate.Equals(lastDate)) { info.CurrentValue 0; } //如果流水号非起始值那么累计计算 if(info.CurrentValue.HasValue info.CurrentValue 0) { currentNumber (int)info.CurrentValue 1;//流水号当前值 } //流水号长度 if(info.ValueLength.HasValue info.ValueLength 3) { serialLength (int)info.ValueLength;//流水号长度 } var SplitString1 string.IsNullOrEmpty(info.SplitString1) ? - : info.SplitString1; var SplitString2 string.IsNullOrEmpty(info.SplitString2) ? - : info.SplitString2; //生成业务编码 businessNumber ${info.Prex}{SplitString1}{currentDate}{SplitString2}{currentNumber.ToString().PadLeft(serialLength, 0)}{info.Suffix}; //更新记录 info.CurrentValue currentNumber; info.SplitString1 SplitString1; info.SplitString2 SplitString2; info.CurrentNumberString businessNumber; info.LastGenerateTime DateTime.Now;//更新最后生成编码日期 await base.UpdateAsync(info); } } catch (Exception ex) { var errorText $生成单号时出现错误{ex.Message}; LogTextHelper.Error(errorText, ex); } finally { syncRoot.Release();//释放锁 } return businessNumber; }上面主要注意的就是流水号的生成这个稍微特殊处理一下如果定义的规则是年月日那么和最后的生成日期和当前日期不一致的话转换为年月日对比就认为流水号重新重置为1否则是同一天的流水号递增即可。如果是年月的也是判断最后日期和当前日期的年月是否一致不一致则重置为1否则递增。注意流水号的编码长度一般为4位如果不满足的可以增加到6位等。最终我们实际的业务编码的管理界面和查看的对应编码的界面如下所示供参考设计界面处理。编辑单个业务编码规则的界面如下所示。为了方便我们这里提供一个【测试生成】的按钮用于测试具体的编码生成我们具体的业务调用就是类似这个调用即可。var handNo await BLLFactoryITableNumberService.Instance.GenerateNumber(tableNameOrCode);同样我们也可以把这个界面搬到WPF框架界面上去可以重用具体的业务编码规则处理如上类似的界面处理。单个通用的业务编码规则的编辑界面如下所示。因此不管对于Winform还是WPF的界面他们的展示方式都是类似的我们可以重用业务层对通用编码规则的定义。本文转载自博客园 - 伍华聪

相关新闻

GitHub 重构漏洞赏金计划:推 VIP 计划、调赏金表,激励优质安全研究!

GitHub 重构漏洞赏金计划:推 VIP 计划、调赏金表,激励优质安全研究!

GitHub 资源导航这里提供了 GitHub 相关的多种资源链接,包括 GitHub 主页、博客、更新日志、文档、客户案例等。还有试用 GitHub Copilot CLI 和参加 GitHub Universe 的入口。此外,按照不同主题分类,有关于人工智能与机器学习、开发者技能、…

2026/7/23 18:18:57阅读更多 →
DAST 检测 MCP 服务器 ANSI 转义序列注入:揭秘攻击变体及防御要点!

DAST 检测 MCP 服务器 ANSI 转义序列注入:揭秘攻击变体及防御要点!

【Bright 相关信息】有 Bright Security,其包含 STAR、Business Impact、Platform、Resources、Partners、Company 等板块,还有 Book a Demo 选项。【ANSI 转义序列注入检测概述】ANSI 转义序列是为终端设计的不可见控制代码,人类查看渲染后的…

2026/7/23 18:18:57阅读更多 →
TM4C1292看门狗定时器原理与实战:从寄存器配置到高可靠设计

TM4C1292看门狗定时器原理与实战:从寄存器配置到高可靠设计

1. 看门狗定时器:嵌入式系统的“安全卫士”在嵌入式系统开发中,最让人头疼的往往不是功能实现,而是系统在无人值守、长期运行后,因为一个未曾预料到的软件缺陷或外部干扰而“死机”。想象一下,一个工业控制设备因为某个…

2026/7/23 18:18:57阅读更多 →
基于GFL_R101_FPN的肠球菌自动检测系统开发

基于GFL_R101_FPN的肠球菌自动检测系统开发

1. 项目背景与核心价值肠球菌检测在医疗诊断、食品安全和环境监测等领域具有重要应用价值。传统检测方法通常依赖人工镜检或培养法,存在耗时长、主观性强等局限性。我们基于GFL_R101_FPN_MS-2x_COCO模型开发的自动检测系统,将目标检测技术引入微生物识别…

2026/7/23 19:37:16阅读更多 →
从思科到软路由:深入理解网络世界的两种维度与身份

从思科到软路由:深入理解网络世界的两种维度与身份

最近刚研究了不少软路由相关的东西,回想起大学课程中有一门和网络工程师相关的思科网络的课程,从RIP协议到OSPF协议,分析网络拓扑图,给交换机路由器敲命令,我还记得那熟悉的命令ip running config,看似它们…

2026/7/23 19:37:16阅读更多 →
为什么你的OpenWrt软路由Web端口修改后无法访问?常见问题排查指南

为什么你的OpenWrt软路由Web端口修改后无法访问?常见问题排查指南

为什么你的OpenWrt软路由Web端口修改后无法访问?常见问题排查指南 最近在折腾软路由的朋友,估计不少人都遇到过这个情况:为了安全或者避开端口冲突,兴冲冲地修改了OpenWrt的Web管理端口,结果保存重启后,浏览器里输入新地址,迎接你的却是一个冷冰冰的“无法访问此网站”…

2026/7/23 19:37:16阅读更多 →
嵌入式系统硬件CRC与向量中断管理:高可靠实时应用的核心技术

嵌入式系统硬件CRC与向量中断管理:高可靠实时应用的核心技术

1. 项目概述与核心价值 在嵌入式系统,尤其是汽车电子、工业控制这类对可靠性要求极高的领域,数据在传输和存储过程中的完整性,以及系统对外部事件的实时响应能力,是决定产品成败的两个基石。前者关乎数据是否正确,后者…

2026/7/23 19:37:16阅读更多 →
DMA控制器原理与应用:从数据搬运到嵌入式系统性能优化

DMA控制器原理与应用:从数据搬运到嵌入式系统性能优化

1. DMA控制器核心价值与设计哲学 在嵌入式系统里,CPU的时间是宝贵的。想象一下,你正在用MCU处理一个实时音频流,每秒钟有数万个采样点需要从ADC搬运到内存缓冲区,然后再进行滤波、编码等运算。如果每个采样点的搬运都让CPU亲自执行…

2026/7/23 19:37:15阅读更多 →
深入解析TI F021 Flash控制器:寄存器配置与诊断模式实战指南

深入解析TI F021 Flash控制器:寄存器配置与诊断模式实战指南

1. F021 Flash控制器:嵌入式存储的“神经中枢” 在嵌入式系统,尤其是汽车电子和工业控制领域,Flash存储器扮演着“非易失性大脑”的角色,负责存储启动代码、应用程序、校准数据和用户配置。然而,直接操作Flash物理阵列…

2026/7/23 19:35:15阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →