news 2026/10/10 17:14:07

免费进销存源码实战:onlyit窗体程序部署与二次开发指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
免费进销存源码实战:onlyit窗体程序部署与二次开发指南

简介:一款面向小型企业和个体经营者的免费进销存管理软件,基于窗体程序开发,提供进货、销售、库存、财务等核心管理功能,并附带OA源码,支持二次开发定制,适用于日常商业运营中的进销存流程优化。资源包共161个文件,约10.99MB,涵盖程序运行所需的dll、bpl动态库与exe可执行文件,同时包含html帮助文档、gif操作示意、xls表格模板、mdb数据库、css/js样式脚本以及reg注册表配置等,便于部署参考与功能扩展。目前已有355人学习下载。软件代码结构完整,从内容预览可见包含多个动态库文件、启动脚本与数据库备份,使用者可借助源码研究进销存业务逻辑,结合窗体界面理解商品台账、库存预警和报表生成机制,也可直接部署试用,降低企业信息化门槛。

1. 一套能改源码的免费进销存:onlyit 窗体程序能帮你做到什么程度

第一次把 onlyit 这套免费进销存装进库房那台旧电脑,是在帮本地一个做五金批发的经销商梳理库存。几百个 SKU 的账已经在 Excel 里彻底炸了,进出库记录全靠一人一张表,月底对账对到半夜还是差两万块。换到 onlyit 之后,首先意识到它和你平时用的 SaaS 进销存不是一回事:这是典型的 C/S 架构窗体程序,点开即用、响应快,数据落在本地数据库里,不依赖浏览器,也不存在按年续费这回事。更意外的是,这套免费版连 OA 审批和角色权限都一并打包了,采购单、销售单的审核可以直接挂到审批流上。对小微企业来说是低成本摆脱 Excel 乱账的方案;对想学真实业务系统的开发者来说,这是一套能直接编译、调试、改功能的完整源码包。

2. 部署前必修课:窗体程序的运行环境、数据库初始化与期初数据迁移

2.1 技术栈判断:为什么窗体程序在小型企业里依然比 Web 版顺手

onlyit121020 版属于典型的 Windows 窗体程序,底层是 .NET Framework。这类软件在企业内网里运行,客户端直连数据库,不经过 Web 中间层。很多做库房管理的人第一次接触这种架构会不适应,觉得它不像现在的网页系统那样打开浏览器就能用。但实际部署过之后会发现,窗体程序在局域网里的体验有很多 Web 版给不了的优势。

对比项窗体程序(本资源)常见 Web 进销存
部署位置每台客户端安装,服务器装数据库服务器部署应用,客户端浏览器访问
网络依赖局域网直连数据库,无外网也能用依赖内网或公网服务可用性
操作响应原生控件渲染,点按无延迟受浏览器和网络延迟影响
数据访问客户端直接读写数据库通过 API 间接访问
离线能力断网不影响已连内网的桌面端服务不可用则整体停摆
源码修改直接打开项目改窗体、编译需要改前端和后台接口

如果你服务的是一家仓库和办公室在同一栋楼、员工十人上下的商贸公司,这种 C/S 架构反而比 Web 版省心:不需要养一个运维去维护 IIS 或 Nginx,也不牵涉域名和 HTTPS 证书。客户端装上就能跑,数据库备份好就万事大吉。

选择这套软件的一个重要理由是“源码完整”。窗体程序的事件、按钮、数据访问层都是可见的,遇到业务上需要调整的逻辑,比如审核后能否反审核、销售单是否允许改价,直接在源码里定位对应事件改掉即可。对比黑匣子一样的商业闭源软件,这种透明度对二开来说非常友好。

2.2 数据库初始化:连接字符串、服务账号与首次登录配置

onlyit 这类窗体进销存通常使用 SQL Server 存放业务数据。拿到安装包之后,先别急着双击主程序,不然八成会因为连不上数据库而白屏。正常的初始化顺序是先把数据库服务准备好,再让程序去连接它。

整个初始化过程分四步:

  1. 安装 SQL Server,Express 版也可以,最低建议 2008 R2 及以上。
  2. 开启 SQL Server 的 TCP/IP 协议,并把服务登录模式改为“混合验证模式”。
  3. 新建数据库实例,创建一个独立的登录账号并赋予 db_owner 权限。
  4. 修改程序目录下的连接字符串配置文件,然后启动主程序。

连接字符串通常存放在 exe 同目录的 app.config 或 exename.exe.config 里。这里给出一个常见的配置写法:

<configuration> <connectionStrings> <add name="MainDb" connectionString="Server=192.168.1.21;Database=OnlyIt_Data;User Id=onlyit_user;Password=YourPass123!;MultipleActiveResultSets=True;TrustServerCertificate=True" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>

逻辑说明:这段 XML 是给程序找数据库用的寻址信息。“Server”指向数据库所在机器的内网 IP,不要写成 localhost,除非程序和数据库在同一台机器;“Database”指定账套库名;“User Id”和“Password”是之前建好的独立登录账号;“MultipleActiveResultSets=True”让同一个连接可以同时跑多个查询,避免快速点按钮时出现“连接忙”报错;“TrustServerCertificate=True”在局域网内不配置证书时使用。

注意一个细节:不要图省事直接在连接串里用 sa 账号。我给一家小店做初始化时图方便用的 sa,后来离职员工拿着管理端密码进了数据库后台。从那以后我始终坚持给账套单独建账号,权限只给这一个库,避免整个实例裸奔。这个习惯也建议你保留。

2.3 期初数据导入:从 Excel 到账套的一次性迁移

程序能正常登录后,下一步就是搬数据。大部分使用场景是从别的软件或纸质账本切换到 onlyit,期初库存、未结采购单、应收应付、供应商和客户档案全部要搬进新账套。

我一般建议分为两个批次导入:先导供应商、客户、商品基础档案,再期初库存。原因很简单:库存明细要关联商品档案,如果商品还没建档,库存导进去也是无主数据,后面盘点会一直对不上。导入模板在安装包的“导入模板”目录里,Excel 列的顺序和表头不能随意改动,常见的列是:仓库编码、商品编码、商品名称、规格型号、单位、期初数量、期初成本。

拿到模板之后,在真正导入之前,先对整理好的 Excel 做一遍数据体检,避免导入中途报错。用 SQL 的方式来看就是重复编码检查:

-- 导入前检测商品档案里是否有重复编码 SELECT 商品编码, COUNT(*) AS cnt FROM 商品档案导入表 GROUP BY 商品编码 HAVING COUNT(*) > 1; -- 导入后核对库存总额,确保期初金额不为负数 SELECT SUM(期初数量 * 期初成本) AS 期初总金额 FROM 期初库存导入表;

逻辑说明:第一段 SQL 统计每个商品编码出现的次数,一旦出现重复值,导入时主键约束会直接把整批数据打回,提示“违反主键约束”。第二段 SQL 用来在导入完成后核对总金额,确保没有负数成本或空单价混进去。参数上要注意,“期初成本”字段在绝大多数情况下应该是含税成本价,不要填销售价,否则后续毛利统计会全线失真。

3. 单据流转与库存联动:采购、销售、调拨的审核状态与处理逻辑

3.1 单据状态机:草稿、审核、过账对库存产生什么影响

进销存系统中最核心的不是界面好不好看,而是单据状态和库存之间的联动关系。onlyit 的采购入库单、销售出库单、库存调拨单基本都遵循一条状态流转线:草稿 -> 审核 -> 过账,少数场景还支持冲销。

状态触发操作库存影响说明
草稿保存无尚未生效,可任意修改
已审核审核按钮按单据方向增减库存锁定,普通操作员不可改
已过账记账按钮已计入成本/应收应付生成对应的财务记录
已冲销冲销按钮反向增减用于单据做错后的更正

这里最容易理解错的地方是“审核”和“过账”的关系。在多数免费版里,审核和过账可能合成一个按钮,点一下就同时完成。但不管是合成还是分开,核心规则不变:库存只在审核那一刻变更。草稿状态下的单据无论怎么改,都不会动库存数量。

实际业务中,我给一家做管材批发的客户部署时遇到一个场景:销售先开了单,但仓库没货,采购还没到。如果开单时直接锁库存,后面发现库存不足就要删单重做。这个系统的处理方式是允许先开草稿单,等采购入库审核后再回来审核销售单。这里提醒一句:只在审核时变更库存,就要求开单员必须养成分两次操作的习惯——先录单,确认库存足够再审核。如果养成了“录完就审核”的肌肉记忆,负库存基本躲不掉。

3.2 组装单与拆装单:按箱进、按个出的多规格商品处理

五金、日化、食品批发行业普遍存在一个现象:进货整箱,出货按个。一箱螺丝 50 盒,每盒 100 个,如果商品档案里只建一个“螺丝”的档案,库存单位到底是箱还是个,永远说不清。onlyit 专门用组装单和拆装单来解决这类问题,这也是它与普通记账软件最大的区别之一。

组装单的逻辑是把多个子件商品合成一个父件商品。例如父件是“螺丝套箱”,子件是 50 盒螺丝和一个外包装箱。审核组装单时,系统自动减少子件库存,增加父件库存。拆装单一反操作,审核后把父件拆回子件。

组装成本的计算有一个关键参数,叫“损耗率”。实际生产中没有哪个组装过程能做到 100% 不浪费,损耗率就是用来摊成本的。成本计算关系:

decimal childTotalCost = 子件成本合计; decimal lossRate = 2; // 百分比,例如 2 表示 2% decimal parentCost = childTotalCost / (1 - lossRate / 100m);

逻辑说明:这段代码计算组装后父件的入库成本。分母中的“1 - lossRate/100”是把损耗摊进成品成本。比如子件总成本是 98 元,损耗率 2%,父件成本就是 98 / 0.98 = 100 元。参数调整上,损耗率对成本的影响很直接:损耗率设高了会虚增库存成本,毛利被压低;设低了成本失真,毛利虚高。我建议实际取数时参考三个月的组装作废记录,别拍脑袋填 5%。系统里这个参数通常在组装单据的工具上设置,不同版本字段名可能叫“损耗率”或“材料损耗百分比”。

3.3 库存预警与积压分析:直接写 SQL 盯数据

窗体进销存普遍自带库存预警界面,但如果数据量大了,或者老板要的是“低于安全库存的 SKU 清单”,直接写 SQL 连数据库查比在界面上翻页快得多。下面是一条典型的库存预警查询:

SELECT p.商品名称, p.规格型号, SUM(s.库存数量) AS 当前库存, p.最低库存, p.最高库存 FROM 库存表 s JOIN 商品档案表 p ON s.商品编码 = p.商品编码 GROUP BY p.商品名称, p.规格型号, p.最低库存, p.最高库存 HAVING SUM(s.库存数量) <= p.最低库存 ORDER BY SUM(s.库存数量) - p.最低库存 ASC;

逻辑说明:先用库存表和商品档案表做关联,按商品维度汇总总库存,再用 HAVING 过滤出低于或等于安全库存的商品。注意这里不能用 WHERE,因为“当前库存”是聚合函数 SUM 的结果,条件只能写在 HAVING 里。参数上,“最低库存”和“最高库存”在商品档案里先维护好,阈值大小直接影响这条查询是否有效。

4. 带 OA 的进销存:审批流、角色权限与源码扩展点

4.1 审核按钮背后的事件驱动逻辑:OA 模块挂在哪个钩子上

onlyit 不止是进销存,搜索关键词里还带了 OA 源码。很多用户只盯着库存功能,把 OA 当摆设。实际拆过源码之后会发现,它的审批中心是独立设计的,并且跟业务单据打通了。

审批流在窗体程序里的实现方式通常是事件驱动:用户在界面上点“审核”按钮,程序先判断这张单据类型是否需要在审批中心走流程,如果需要,就生成一条待办任务,把单据状态置为“审批中”,等审批人处理后,再回调单据审核接口。下面这个 C# 片段是我在二次开发时常用的判断逻辑:

// 单据审核前检查是否需要走审批流 if (order.RequireApproval && approvalService.GetApprovalStatus(order.Id) != ApprovalStatus.Approved) { MessageBox.Show("单据未完成审批,无法过账", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } approvalService.Submit(order.Id, currentUser.Id, "提交采购审批");

逻辑说明:代码先检查订单对象上的“RequireApproval”布尔字段,这个字段在单据类型表里配置,哪些单据需要审批由管理员在界面上勾选。“GetApprovalStatus”是审批服务提供的方法,返回当前单据在审批流中的状态。只有已经 Approved 的单据才允许继续过账。“Submit”方法提交待办任务,参数是单据号、当前操作人 ID 和审批说明。如果把“RequireApproval”改成永远为 true,整条业务单据链路就会卡在审批环节,所以这个字段的默认值在初始化时要根据业务确认清楚。

4.2 角色权限配置:菜单、按钮和数据可见范围怎么控制

权限系统对于一个带 OA 的进销存来说,实际作用比表面上看到的更重要。仓库管库存、财务管成本、业务管客户,如果所有操作员都能审核销售单,内控等于零。onlyit 的权限模型是典型的“操作员 -> 角色 -> 权限点”三层结构,权限点精确到窗体和按钮。

SELECT r.角色名称, p.权限标识 FROM 角色表 r JOIN 角色权限表 p ON r.角色ID = p.角色ID WHERE p.权限标识 LIKE '单据.销售%' ORDER BY r.角色名称;

逻辑说明:通过角色权限关联表查出每个角色在“销售单据”这个模块下拥有的权限点。权限标识的命名规则一般是“模块.功能点”,比如“单据.销售审核”“库存.盘点执行”。二次开发新增一个按钮时,记得在权限表里插入对应的权限记录,否则窗体上按钮会正常显示,但点击时提示“当前用户无权执行”。

这里有一个实际踩过的坑:给 A 角色分配了“销售单审核”权限,但操作员登录后审核按钮是灰色的。后来排查发现,角色确实有权限,但操作员的账号没有被挂到这个角色上,系统里新增操作员时“绑定角色”和“录入密码”是两个独立步骤,漏掉绑定角色,账号就属于无角色状态,按钮权限全部缺失。

4.3 把 OA 模块真正用起来:请假、报销和采购申请共用一条审批链

很多小微企业引入进销存只是要一本库存账,OA 模块往往被冷落。但实际用起来之后会发现,只把业务单据放进 OA 是浪费。onlyit 自带的 OA 功能至少包含三类常用审批:请假申请、费用报销、采购申请。

这三类申请走的是同一条审批链路:申请人填写单子 -> 提交 -> 部门负责人审批 -> 财务/老板终审 -> 归档。相比微信里发条消息等回复的方式,它的价值在于每一笔审批都有单据号、时间戳和最终意见,月底想复盘“这个月采购申请到底批了多少”的时候,直接查审批中心就能拉出明细。采购申请审批通过后,还能一键关联生成采购订单,这在源码层面是通过“源单”字段实现的。

从部署角度说,OA 模块的初始化比进销存简单得多:关键是先把组织架构维护好。组织架构表里要体现上下级关系,审批流才能按“上级审批”规则自动路由。如果导入员工时没有维护汇报关系,审批单到了待办列表里就只能手动指定审批人。

5. 避坑指南:窗体程序实战中的五个典型翻车现场

5.1 数据库连不上,程序启动直接白屏

现象:双击主程序后没有弹出登录窗,直接抛“在与 SQL Server 建立连接时发生与网络相关或特定实例的错误”,或者干脆停留在灰色空白窗体。

原因:最常见的是 SQL Server 服务没启动,其次是 TCP/IP 协议被禁用,再就是连接字符串里 Server 字段写成了“localhost”而数据库在另一台机器。这套软件使用的是数据库直连模式,任何一环不通都会导致程序启动异常。

解决:先确认服务器上 SQL Server 服务已启动,客户端和服务端能互相 ping 通。然后在服务器上打开“SQL Server 配置管理器”,把“SQL Server 网络配置 -> 协议 -> TCP/IP”改为“已启用”,并重启 SQL Server 服务。最后检查 app.config 里的连接字符串,Server 字段必须是数据库服务器的实际 IP,而不是 localhost。

5.2 库存变负数,月底盘点账实不符

现象:商品档案里没做过出库单,库存表里却出现了负数;或者盘点时发现实物还有 20 件,系统账面却是 -5 件。

原因:多数是单据审核顺序倒置——先审核了销售出库单,之后才补做采购入库单,并且系统参数允许负库存出库。这在“先出货后补单”的小公司里太常见了,业务着急,系统又没拦住,最后账目只能靠盘点调整找平。

解决:优先检查系统参数里的“允许负库存”开关,不要为了图方便留在开启状态。已经出现的负库存,正确做法不是直接改库存表,而是找到那张问题出库单反审核,把审核顺序理顺之后再重新审核。如果单据数量已经积压到月底,最快的止损方案是做一张盘点单,把账面调整为实物数量。

5.3 审核按钮没反应,审批流不触发

现象:操作员有审核权,点了“审核”按钮,窗体没提示、单据没变化,像什么都没发生过。

原因:多半是审批流配置和角色权限两处中的一处出了问题。要么这张单据类型被勾选了“需要审批”,但审批流程定义里没有配置任何审批节点,导致提交后无人处理;要么操作员账号没挂角色,按钮事件里做了权限判断后直接 return。

解决:先去单据类型设置里确认“需要审批”的勾选状态,再去审批流定义确认该单据类型至少有一个审批节点。同时用上面第 4.2 节的那条 SQL 查询,确认操作员对应的角色确实拥有该按钮的权限点。按钮事件的源码如果加了日志,打开日志文件能看到具体阻断位置,按日志提示逐层排除。

5.4 多人同时开单,保存时程序卡死或报“该死锁”

现象:月底集中开票时,两个以上操作员同时保存单据,其中一个界面弹“事务死锁”,单据保存失败。

原因:窗体程序客户端直连数据库,默认事务隔离级别下,两个事务同时更新同一张单据主表时会发生锁竞争。尤其是销售开单时同时写入单据头、单据明细、库存流水和多张关联表,锁升级和死锁的概率会明显提升。

解决:常规做法是把事务隔离级别调整为“读已提交”,并让业务逻辑里先更新主表再更新明细表,所有操作保持一致的加锁顺序。此外在连接字符串里启用 MARS(MultipleActiveResultSets=True)能缓解同一连接上多个查询相互阻塞的问题。还要叮嘱操作员,同一份单据不要开两个窗口重复编辑。

5.5 升级新版本后旧账套打不开

现象:从旧版本覆盖安装到 121020 版,启动后提示“数据库版本过低”或“无法附加账套”,旧数据好像凭空消失了。

原因:新版程序的数据结构可能加了字段、改了表结构,旧账套没有随程序同步升级。很多 Windows 窗体程序做升级时,程序文件更新了,但数据库升级脚本没有自动执行。

解决:在覆盖安装前,先通过数据库管理工具把账套库做一次完整备份。升级后如果提示版本不匹配,在安装包目录里找到“数据库升级脚本”目录,按版本号从低到高逐级执行 SQL 脚本。切记不要直接用新程序去附加旧数据文件,先执行升级脚本再启动程序。这套流程我也翻车过一次,后来凡是涉及版本升级,备份账套成为我的固定动作。

6. 备份、防呆与二次开发的三个落地习惯

6.1 用 SQL 命令做定时备份,不依赖人工点按钮

窗体进销存的数据全在数据库里,数据库挂了,一切归零。这套软件自带备份功能,但它的备份逻辑依赖主程序界面操作,如果服务器上的程序一直没打开,备份也就停了。我更习惯直接在数据库服务器上加一个 SQL 作业,每天凌晨自动备份。用一条简单的 sqlcmd 命令就可以验证备份可用:

sqlcmd -S 192.168.1.21 -U onlyit_user -P YourPass123! -Q "BACKUP DATABASE OnlyIt_Data TO DISK='D:\backup\onlyit_$(date +%Y%m%d).bak' WITH FORMAT, INIT"

逻辑说明:这条命令通过 sqlcmd 工具连接 SQL Server,执行 BACKUP DATABASE 语句生成备份文件。$(date +%Y%m%d) 是脚本层面的日期拼接,让备份文件名按天变化。加 WITH FORMAT 和 INIT 表示覆盖同名文件并重建备份媒体集。参数配置上,注意把备份路径 D:\backup 先建好,SQL Server 服务账号对该目录要有写入权限,否则作业会一直报错但备份文件始终不出现。

6.2 改源码前先做三件事:备份、记录原逻辑、小步编译

二次开发时最容易翻车的不是写不出代码,而是改完编译通过后,连锁影响了好几处原有功能。我的习惯是:任何改动之前先备份财务相关模块的源码目录,然后在代码里用注释记录原始逻辑,最后每次只改一个功能点就编译一次测试。不要一次性改十个地方再统一编译,窗体程序如果报错,定位问题的成本会成倍增加。

像给销售单加一个“客户备注”字段这种需求,完整路径是:数据库里给销售单明细表扩展字段 -> 在窗体设计器里拖一个文本框 -> 绑定数据源字段 -> 修改保存逻辑补齐字段写入。每一步都很直接,但每一步都可能在编译时报“找不到字段”的错误——因为数据访问层的实体类没有同步更新。记住:加数据库字段,同步改实体类、数据访问接口、窗体绑定这四层,少改一层编译就过不去。

从那次数据库升级翻车之后,我每次给客户交付这套系统,强制自己走一遍从备份数据库到新建账套、导入少量测试数据、开单审核出库的完整流程,哪怕客户催得再急也不能省。这套系统虽然免费,但一旦用起来就是公司的业务命脉,小心一点总归没错。希望这份拆解能帮你在部署和二次开发时少走几段弯路。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 17:14:05

GPU内核驱动安全与稳定性实战:内存漏洞、IOCTL攻防与TDR恢复

这一节&#xff0c;我们进入专栏第四部分“高级主题与实战”的4.3节。如果你跟着前面几节走到了现在&#xff0c;应该已经知道KMD&#xff08;Kernel Mode Driver&#xff0c;内核模式驱动&#xff09;的工作范围包含了命令提交、内存管理、电源控制、上下文切换等大量危险地带…

作者头像 李华
网站建设 2026/10/10 17:13:15

Spring Boot汽车维修保养系统设计:从业务流程到毕业设计落地

毕业设计这个圈子流传一句话&#xff1a;管理系统遍地走&#xff0c;但能不能拿到高分&#xff0c;看的是你有没有把"业务"真正装进代码里。今天要拆解的题目是"基于Spring Boot的汽车维修保养服务信息系统"&#xff0c;这个标题看起来平淡&#xff0c;其实…

作者头像 李华
网站建设 2026/10/10 17:11:01

12GB显存跑125B大模型:分层卸载与量化压缩实战

1. 12GB显存跑125B模型&#xff0c;这事到底靠不靠谱先把结论摆在前面&#xff1a;12GB显存的消费级显卡&#xff0c;确实可以运行125B参数级别的大模型&#xff0c;但前提是你得接受"分层卸载量化压缩CPU协同"这套组合拳&#xff0c;而不是指望模型全部塞进显存里。…

作者头像 李华
网站建设 2026/10/10 17:10:42

快手电脑版2026最新版Windows安装与兼容性深度指南

1. 项目概述&#xff1a;为什么“快手电脑版”安装这件事&#xff0c;远比看起来复杂得多“2026最新版快手电脑版下载与安装全攻略”这个标题&#xff0c;表面看是个再普通不过的软件安装教程&#xff0c;但作为连续三年深度参与多个主流短视频平台桌面端适配项目的从业者&…

作者头像 李华
网站建设 2026/10/10 17:09:41

基于Android的高校校史展厅管理小程序设计与实现

每年这个季节&#xff0c;后台总会涌入大量关于毕业设计的问题。今年问得最多的&#xff0c;不是“怎么做”&#xff0c;而是“我能用它做什么”。我接到的这个项目比较典型——基于Android的高校校史展厅管理小程序设计与实现&#xff0c;班里同学拿它当毕设&#xff0c;从提交…

作者头像 李华
网站建设 2026/10/10 17:08:18

010 Editor 实战:用模板解析二进制文件结构

简介&#xff1a;一款面向开发与逆向分析场景的010 Editor编辑器资源&#xff0c;兼顾十六进制、文本、二进制和源代码四种编辑模式。它能快速加载超过4GB的十六进制文件&#xff0c;支持ASCII、Unicode、EBCDIC及中日韩等多国字符集&#xff0c;并提供无限撤销、书签、强调规则…

作者头像 李华