ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ASP.NET进销存源码:从部署到二次开发实战指南

ASP.NET进销存源码:从部署到二次开发实战指南 简介基于ASP.NET的ERP进销存管理系统完整源码适合.NET方向初学者、课程设计或毕业设计使用也可供需要了解传统进销存业务流程的开发人员参考。该系统围绕采购、销售、库存等核心业务设计开发环境为Visual Studio 2010与SQL Server 2008R2基于.NET 4.0数据库文件置于DB_sq文件夹附加数据库后修改web.config连接字符串即可运行默认管理员账号与密码均为8001。资源包总大小27.33MB共2000个文件其中C#源代码文件460个、ASPX页面351个、JavaScript脚本802个、CSS样式120个并包含数据库备份、项目配置、图片图表、Excel表格及公共控件类文件基本覆盖前端交互、后台业务逻辑到数据库存储的完整链路。目前已有243人学习通过这套源码可以梳理ASP.NET多层架构、控件封装、权限登录与库存流转等关键实现对快速搭建演示环境和二次开发很有帮助尤其适合做课程答辩或项目复现。1. 一套ASP.NET进销存源码还值不值得用先看它能给你省什么最近不少朋友发消息问现在都在聊ASP.NET Core、Vue3后台管理系统甚至SpringBootVue商品管理系统一套老ASP.NET的ERP进销存源码还有啥可看我的答案是如果你是要给中小工厂、商贸公司做一套能用的进销存管理系统这种老源码反而是最快跑通的选项。它把采购、销售、库存、应收应付几件事闭环了你拿来改二次开发比自己从零写SaaS快太多。适合接单的工程师也适合想弄懂真实业务流的新手。打开源码第一件事不是崇拜技术而是看它能不能算清账。2. 看懂ERP源码的骨架ASP.NET老项目为什么长这样目录、数据库、访问层怎么配合拿到一套ERP进销存源码别急着按F5。先打开解决方案看文件后缀。如果是.aspx、.ascx、.ashx基本就是ASP.NET Web Forms。很多人一看见Web Forms就皱眉但国内还在线上跑的中小企业ERP一大半还是Web Forms写的甚至有些是从Delphi 7的进销存迁移过来的。这不是说Web Forms有多先进而是它足够稳改起来门槛低。一个页面配一个.aspx.cs出问题打开文件就能改不需要理解复杂的中间件管线。所以我看到这类源码的第一反应是先把它跑通再看它在哪些地方值得重构而不是全盘推翻。2.1 ASP.NET WebForms仍是中小ERP主力Core和MVC是迁移方向为什么Web Forms能活到今天原因在回发模型。控件拖上去事件写在后置代码开发体验接近老的WinForm。对于没有专职前端的团队后端工程师一个人能搞定录单页面、列表、权限这是很大的优势。而ASP.NET Core MVC虽然新但要求你理解Startup、依赖注入、Razor布局、中间件改一个页面要动的文件更多。如果你拿到源码后想用ASP.NET Core MVC重写等于把业务重做一遍风险远大于收益。我的判断是新项目可以优先选ASP.NET Core MVC或者Vue3后台管理系统做前后端分离手上已经能跑的ERP源码最佳路线是保留WebForms作为录入端在项目里加Web API接口。老ERP也可以同时提供JSON接口给手机端或新前端调用。这样既不动核心录单流程又能让仓库扫码枪、老板手机报表这些新场景接入。2.2 源码目录里的三层UI层、BLL层、DAL层各管什么拿到源码先看解决方案结构。典型的长这样ERP.sln ├─ Web // UI层aspx页面 用户控件 │ ├─ Common/ // 公共类Session判断、权限控件、工具函数 │ ├─ Pages/ │ │ ├─ Purchase/ // 采购采购单、入库单、退货单 │ │ ├─ Sales/ // 销售销售单、出库单、客户管理 │ │ ├─ Inventory/ // 库存库存查询、调拨、盘点 │ │ └─ Finance/ // 应收应付、收款付款单 ├─ BLL // 业务逻辑单据编号、库存校验、允许负库存判断 ├─ DAL // 数据访问SQL语句或存储过程 ├─ Model // 实体类对应数据库表 └─ DB // SQL脚本建库、建表、初始数据别指望每套都规范。很多老源码其实是“两层半”页面里直接new SqlConnection业务逻辑都写在.aspx.cs里。这种反而好改因为改动集中搜索“SqlConnection”就能定位所有数据访问点。我拿到源码会先全局搜“SELECT”和“INSERT”看SQL是写在DAL的一个大文件里还是散在页面。如果集中在DAL层说明作者有分层意识如果散在页面里也别急先跑通二次开发时把要改的查询抽到DAL。给一个DAL层典型方法注意参数化public DataTable GetStockList(string keyword) { using (SqlConnection conn new SqlConnection(connectionString)) { string sql SELECT p.ProductCode, p.ProductName, ISNULL(s.Quantity,0) AS Quantity FROM Product p LEFT JOIN Stock s ON p.ProductId s.ProductId WHERE p.ProductCode LIKE kw OR p.ProductName LIKE kw ORDER BY p.ProductCode; using (SqlCommand cmd new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue(kw, % keyword %); SqlDataAdapter da new SqlDataAdapter(cmd); DataTable dt new DataTable(); da.Fill(dt); return dt; } } }这里用LEFT JOIN是因为有些商品还没有建立库存记录如果改用INNER JOIN这类商品在列表里就消失了业务上会以为漏数据。参数化是必须的ERP源码里被SQL注入了整张商品表都可能被删。老代码里常见“string sql select * from Product where Name txtName.Text ”这种写法必须改没有商量。再补一段BLL层的事务边界。看源码时搜“BeginTransaction”如果只有新增订单时用说明作者把多表写操作当成一个原子操作。这样库存流水和单据才不会一半成功一半失败。有些源码连事务都没用入库单主表插进去了明细插到一半报错库存却已经加上月底对账就全靠手工。这种源码拿来练手可以直接上生产要慎重。2.3 数据库脚本进销存核心表的主外键关系进销存系统的数据库不会很复杂但表与表之间的关系必须看明白。常见核心表如下表名用途关键字段Product商品ProductId, ProductCode, ProductName, 单位, 库存上下限Stock当前库存ProductId, WarehouseId, QuantityStockLog库存流水LogId, BillType, BillNo, ProductId, ChangeQty, CreateTimePurchaseOrder采购单主表OrderId, SupplierId, TotalAmount, Status, CreateTimePurchaseOrderDetail采购单明细OrderId, ProductId, Quantity, Price, AmountSaleOrder销售主表OrderId, CustomerId, TotalAmount, Status, CreateTimeSaleOrderDetail销售明细OrderId, ProductId, Quantity, Price, AmountARAP应收应付客户/供应商, 方向, 单据号, Amount, Balance这里最关键的不是主外键约束而是StockLog这张流水表。只要每次入库出库都写流水月底库存对不上时还能按流水追到具体单据。很多源码为了省事只更新Stock表里的Quantity不写流水或者流水里不带单据号一出问题连翻盘的机会都没有。所以看源码时要搜“INSERT INTO StockLog”搜不到就要警惕这就是我常说的“后悔药”。继续给出一个联表流水查询SELECT l.LogId, l.BillType, l.BillNo, p.ProductName, l.ChangeQty, u.UserName, l.CreateTime FROM StockLog l LEFT JOIN Product p ON l.ProductId p.ProductId LEFT JOIN SysUser u ON l.CreateBy u.UserId WHERE l.ProductId ProductId ORDER BY l.CreateTime DESC;StockLog表必须建索引至少要有(ProductId, CreateTime)。没有索引时库存详情页一查就是全表扫描数据量到10万行就开始“转圈”。我在接一个老项目时就从日志里看到这种慢查询加完索引查询从8秒掉到300毫秒。还有一个细节现代进销存会在库存表里加LockQty锁定数量。销售订单已审核未发货时把数量记到LockQty发完货再减。这样才能避免“订单占了货别人还能卖”的情况。老源码如果只有Quantity那就要在业务上规定“审核即扣减”但这样订单取消时又要把库存加回来逻辑绕来绕去。能看得懂这个区别就算是把骨架看懂了。3. 把源码跑起来本地IIS部署、数据库还原和连接字符串的坑拿到源码一定先在自己电脑上跑通再往客户服务器上放。这套ASP.NET ERP对运行环境有要求最好在Windows上用Visual Studio SQL Server。下面是我验证源码时走的完整流程。3.1 环境准备Visual Studio版本、SQL Server和IIS组件先看Web项目文件里的TargetFramework。如果是.NET Framework 4.x用Visual Studio 2019或2022都能处理如果是3.5版本用VS2019打开后建议先不要盲目升级直接右键项目选“属性”把目标框架改成4.7.2然后编译试试。老源码如果用到了第三方控件升级目标框架可能触发授权问题所以先保持原样能跑通再动。SQL Server用2019或2022都行Express版也能跑只是有数据库大小限制。还原数据库时注意源码里数据库名可能是ERP但你一定要还原成Initial Catalog对应的名字。如果连接字符串写的是“databaseERP”你还原成ERP_test不改连接字符串永远连不上。IIS组件这一项最容易翻车。Windows功能里要勾选“.NET Framework 3.5/4.8 功能”和“IIS的ASP.NET”模块否则发布到IIS后浏览器直接500.19或者“处理程序 PageHandlerFactory 未找到”。我一直用命令行一次性装好dism /online /enable-feature /featurename:NetFx3 /featurename:NetFx4-AdvAspNet dism /online /enable-feature /featurename:IIS-WebServerRole /featurename:IIS-ASPNET注意NetFx3是3.5运行时老ERP经常需要NetFx4-AdvAspNet是ASP.NET 4.x运行。装完IIS后记得重启站点。这个报错非常玄学其实环境没装对。3.2 还原数据库并改连接字符串搜索“Data Source”是第一步打开SQL Server Management Studio右键“数据库”→“还原”。然后打开Web.config找到connectionStrings节点。常见写法connectionStrings add nameERPConnection connectionStringdata source.;initial catalogERP;user idsa;password你的密码;MultipleActiveResultSetsTrue providerNameSystem.Data.SqlClient / /connectionStrings参数说明data sourcelocalhost或者服务器IPinitial catalog是数据库名user id/password是SQL登录账号不要用“Integrated SecurityTrue”发布到服务器时还要改回本地。MultipleActiveResultSets建议保留老代码经常一次性开多个DataReader。重点来了连接字符串很可能不止在Web.config里。有的是在DAL层静态类里写死“server192.168.1.100”。所以必须全局搜索“Data Source”或“server”把所有漏网之鱼找出来。我接手一个项目时改完Web.config还是连不上最后发现Model层有个ConnectionHelper.cs里面又写了一份。如果连接字符串被加密了怎么办常见做法是在WebConfig里看到EncryptedData这时用aspnet_regiis -pd解密或者找源码里是否有解密函数。有些源码作者会保留明文只是加了注释。不要自己猜搜索“Decrypt”更快。3.3 编译与部署直接运行和发布到IIS是两套逻辑在Visual Studio里按F5会用IIS Express跑起来这是最快的验证方式。如果项目引用了一些老包先右键解决方案“还原NuGet包”。有些源码带的packages文件夹在压缩包里解压后不还原也能编译。发布到IIS时我一般右键Web项目“发布”→“文件夹”目标路径指到服务器网站根目录。然后在IIS里创建应用程序池选择.NET Framework v4.0经典或集成。这里有个老坑如果源码用了“集成管线”下无法识别的处理程序就切到“经典”模式。反过来如果用了ASP.NET Routing必须用集成模式。所以部署后先看一眼网站是否能打开“Login.aspx”如果500再切换模式。还要给网站目录写权限。老ERP经常要写日志、生成Excel、上传商品图片默认的IIS_IUSERS只给读造成保存单据报错。解决办法是给网站的“写入”权限同时把图片上传目录排除在写权限外会更安全。如果只是内部测试也可以把VS发布出来的文件夹复制到服务器然后创建一个“应用程序”指向这个文件夹。注意不是把源码放上去而是发布后的文件加上bin目录。整套流程跑通后建议把网站日志打开排查500时看Windows事件查看器里ASP.NET 2.0/4.0的异常。为了减少“黑匣子”问题我把web.config里的customErrors mode改为Offsystem.web customErrors modeOff/ compilation debugtrue targetFramework4.7.2/ /system.web这样页面报错会显示明细行。生产环境记得改回On不然错误堆栈会暴露SQL语句。3.4 部署后先调的三个配置项Session超时、上传大小、连接池老ERP默认Session 20分钟用户中午休息一会儿回来就掉线。在web.config:system.web sessionState modeInProc timeout60 cookielessfalse / /system.web说明InProc是最常见模式但应用池回收会丢Session。如果你站点部署在单机调大timeout即可如果在多台服务器必须改成StateServer或SQLServer。判断依据是看站点是单机还是负载均衡。第二个是上传大小。商品图片经常超过浏览器默认的4MB限制。在system.webServer里security requestFiltering requestLimits maxAllowedContentLength104857600 / /requestFiltering /security同时给页面上的FileUpload设置maxRequestLength。第三个是数据库连接池。老源码频繁new SqlConnection关闭不及时会导致连接池耗尽。最稳妥的做法是用using包裹连接并设置连接字符串的PoolingTrue默认就是。如果连接池爆了看报错“Timeout expired”多半是有的连接没Close。4. 进销存主流程的代码实现采购入库、销售出库和库存扣减的闭环进销存源码的核心不是界面是几个“写操作”的代码。把采购入库、销售出库、库存盘点这几个事务读透这套系统你就能改。4.1 采购入库单提交时代码如何同时写主表、明细和库存流水老ERP保存采购入库单最少要动四张表采购主表、采购明细、库存表、库存流水。看下面这段典型事务代码using (SqlConnection conn new SqlConnection(connectionString)) { conn.Open(); SqlTransaction tran conn.BeginTransaction(); try { // 1. 插入采购入库主表拿到自增单号 string sqlMaster INSERT INTO PurchaseOrder(SupplierId, TotalAmount, Status, CreateBy, CreateTime) VALUES(SupplierId, TotalAmount, 已审核, CreateBy, GETDATE()); SELECT SCOPE_IDENTITY();; SqlCommand cmdMaster new SqlCommand(sqlMaster, conn, tran); cmdMaster.Parameters.AddWithValue(SupplierId, supplierId); cmdMaster.Parameters.AddWithValue(TotalAmount, totalAmount); cmdMaster.Parameters.AddWithValue(CreateBy, userId); int orderId Convert.ToInt32(cmdMaster.ExecuteScalar()); string billNo PO orderId.ToString().PadLeft(6, 0); // 2. 循环写明细 库存 流水 foreach (var item in details) { SqlCommand cmd new SqlCommand( INSERT INTO PurchaseOrderDetail(OrderId, ProductId, Quantity, Price, Amount) VALUES(OrderId, ProductId, Quantity, Price, Amount); IF EXISTS(SELECT 1 FROM Stock WHERE ProductIdProductId AND WarehouseIdWarehouseId) UPDATE Stock SET QuantityQuantityQuantity WHERE ProductIdProductId AND WarehouseIdWarehouseId; ELSE INSERT INTO Stock(ProductId, WarehouseId, Quantity) VALUES(ProductId, WarehouseId, Quantity); INSERT INTO StockLog(BillType, BillNo, ProductId, ChangeQty, CreateTime) VALUES(采购入库, BillNo, ProductId, Quantity, GETDATE());, conn, tran); cmd.Parameters.AddWithValue(OrderId, orderId); cmd.Parameters.AddWithValue(ProductId, item.ProductId); cmd.Parameters.AddWithValue(Quantity, item.Quantity); cmd.Parameters.AddWithValue(Price, item.Price); cmd.Parameters.AddWithValue(Amount, item.Quantity * item.Price); cmd.Parameters.AddWithValue(WarehouseId, warehouseId); cmd.Parameters.AddWithValue(BillNo, billNo); cmd.ExecuteNonQuery(); } tran.Commit(); } catch { tran.Rollback(); throw; } }逻辑说明这个方法是典型的“一个事务管四张表”。注意我故意把单据编号用自增ID拼出来为的是让你看清楚编号是怎么生成的。真实项目里单据号一般单独建BillNo表用存储过程批量生成避免并发拿重号。所以你在源码里看到“SELECT MAX(BillNo)”这种写法要小心多用户同时点保存可能拿到同一个单号。解决方式是建唯一索引或者改成“独立编号表 行锁”。这一步很关键。参数说明加参数用AddWithValue是偷懒正式代码最好用SqlDbType明确类型。AddWithValue在SQL Server上对NVarChar和DateTime有时会造成隐式转换导致索引失效。这也是老源码性能差的一个隐藏点。4.2 销售出库扣库存先查后扣为什么会超卖锁和事务怎么写很多简单系统用的是“先查库存再扣”的写法看起来没毛病一上多人就出事// 反例先查再扣两个请求同时读到库存10都会通过最后超卖 int stock GetStock(productId); if (stock qty) { UpdateStock(productId, stock - qty); }原因在于两个销售员同时录单都读到可用库存10A扣了8B也扣了8账面就变成-6。这是进销存并发里最经典的“超卖”问题。解决的办法是直接把库存条件写进UPDATE用受影响行数判断string sql UPDATE Stock SET Quantity Quantity - Qty WHERE ProductId ProductId AND Quantity Qty; IF ROWCOUNT 0 THROW 50001, 库存不足, 1;; SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(Qty, qty); cmd.Parameters.AddWithValue(ProductId, productId); cmd.ExecuteNonQuery();参数里的Qty是本次出库数量ProductId是商品ID。重点是“Quantity Qty”这个条件它让数据库在扣减的同时完成校验一个语句就是原子操作。如果受影响行数为0就抛错回滚这样不会出现负数库存。如果用的SQL Server版本较老不支持THROW可以用RAISERROR。有些源码还会要求负库存不允许过账那就在UPDATE前再加一个锁查询SELECT ... WITH(UPDLOCK)。但最稳妥的还是UPDATE条件判断因为它不需要额外锁。还要注意扣完库存后必须写一条“销售出库”流水并且关联销售单号。如果客户退货就写一条负数的出库流水或者“销售退货”类型让对账时有来有回。很多源码直接“删除出库记录”来冲正这是错误的做法审计时会死。4.3 应收应付与库存对账月底不平的常见原因库存和财务对不上通常不是数量记错是成本算法不一致。老ERP很多用“最近进价”给出库成本这在新旧采购单价相差很大时月底库存金额全是乱的。正确做法是移动加权平均// 新成本 (原库存金额 本次入库金额) / (原库存数量 本次入库数量) decimal newCost (oldQty * oldCost buyQty * buyPrice) / (oldQty buyQty);这段计算必须放在入库事务里不能放到page里。如果两个采购单同时入库同一商品两个请求都读到旧成本计算出的新成本就会互相覆盖。所以成本计算和入库单要同一个事务且对商品行加锁。应收应付不平还有一大半原因是核销没做干净。老源码经常是客户付款后直接更新ARAP表的Balance字段没有记录“这张收款单核销了哪几张销售单”。月底对账时财务只能看到余额解释不清。我建议二次开发时至少加一张“核销明细表”记录收款单号、来源单号、核销金额。ARAP表只留当前余额所有变动走流水。这样即使有一笔付款对错了单子也能在流水里翻出来重挂算是给自己留一张后悔药。4.4 盘点单的代码写法盘盈盘亏不是直接改库存数字盘点时账面数是Stock.Quantity实际数来自Excel或扫码枪差异要生成一张盘点单然后通过StockLog写“盘盈/盘亏”流水。禁止直接UPDATE Stock必须留痕迹。给一个SQLINSERT INTO StockLog(BillType, BillNo, ProductId, ChangeQty, Remark) VALUES(盘点调整, CheckNo, ProductId, DiffQty, Remark); UPDATE Stock SET Quantity Quantity DiffQty WHERE ProductId ProductId;说明DiffQty可正可负但要与盘点单明细一一对应。老源码里很多没有盘点流程只有“调整库存”按钮。这种要小心审计。5. 改这套ERP源码最容易踩的5个坑从登录超时到页面乱码改老ERP源码比写新系统更容易翻车因为代码里藏着很多隐性约定。下面五个坑我基本都踩过按现象、原因、解决写清楚。5.1 改了页面后所有操作跳回登录页Session失效和IIS应用池回收现象登录进去点保存单据页面直接跳回Login.aspx。反复登录也没用。原因老ERP用Session存登录状态默认是InProc进程内。IIS应用池有个“闲置超时”默认20分钟一旦回收进程里的Session全部清空。另外Web.config里如果sessionState timeout是20用户挂机超时也会掉线。还有一种情况代码里在Application_Start中预加载了数据字典只要这个事件异常所有Session也变相失效。解决把Session超时调到60或120分钟并让应用池“闲置超时”设为0即不超时回收。如果有多台服务器必须改SessionState为StateServer或SQLServer否则单机这招只能稳住一台。再有写一个全局的LoginBasePage在Page_Load里判断Session[User]不要在每一个页面复制粘贴判断逻辑。5.2 日期查询总差一天闭区间查询和时区偏移现象用户选“2025-06-10”当天的订单查不出来只有9号及之前的。原因查不到当天是因为老代码把TextBox的文本当成“2025-06-10 00:00:00”数据库里的CreateTime是“2025-06-10 15:30:00”用“CreateTime 2025-06-10”就把当天所有时间给排除掉了。还有另一个时区坑浏览器JavaScript从Date对象序列化时会按UTC生成“2025-06-09T16:00:00Z”某一些老控件直接绑定隐藏字段导致服务器拿到的是前一天。解决统一在服务端解析日期并且查询条件改成半开区间“CreateTime start AND CreateTime end”其中end传入“结束日期 1天”。不要用LIKE来匹配日期也不要对CreateTime做CONVERT截断否则索引失效。5.3 列表超5万行就卡GridView自带分页是假分页现象库存流水打开10万行页面等了十秒翻下一页又等十秒。原因GridView搭配SqlDataSource自带AllowPaging默认分页是先不分页地把所有行Select出来再在控件层跳过。数据量一大数据库、带宽、页面内存全部被拖垮。很多老ERP都有这种列表。解决改成服务端分页。SQL Server 2012以上可用OFFSET/FETCHSELECT * FROM StockLog ORDER BY LogId DESC OFFSET PageSize * (PageIndex - 1) ROWS FETCH NEXT PageSize ROWS ONLY;或者用ROW_NUMBER()然后做两个连接一个查总数一个查当前页。我一般会把分页参数放存储过程避免把动态SQL拼到前端。改完这一步10万行列表也能秒开。5.4 新菜单分配了权限但用户看不到缓存失效和菜单表条件现象管理员给角色新增了一个菜单重新登录还是看不到。原因老系统为了省去每次请求都查数据库在Application或Session里缓存了菜单树。角色权限变更后没有清缓存。还有一种很隐蔽的是菜单表里的菜单项IsDeleted0或IsVisible1新增时默认值不对。解决找到缓存键一般搜索“MenuTree”或“Permission.GetMenu”。修改角色权限时调用Cache.Remove。如果怎么都找不到最简单的办法是重启IIS应用池先确认是不是缓存问题。但真正根除还是给权限表加Version在菜单树缓存键里带上版本号授权时Version自增新请求拿到的就是新菜单。做二次开发时我会优先用Session存userId和roleId菜单动态回读不做缓存。5.5 导出Excel中文乱码BOM头和Response.ContentEncoding现象页面生成CSV用Excel打开中文全是“锟斤拷”。原因Response.ContentEncoding没设UTF-8或者设了但没有写BOM。老浏览器和Excel对无BOM的UTF-8识别成ANSI。解决在输出前加BOM头Response.Clear(); Response.ContentEncoding Encoding.UTF8; Response.ContentType text/csv; charsetutf-8; Response.Write(\uFEFF); // 然后写数据 Response.End();注意不要先Response.End再写。如果文件名里有中文还要记得用HttpUtility.UrlEncode否则另存为时文件名乱码。这个办法对CSV和XML通用。以上五条前三条大多是环境问题后两条是代码问题。遇到时先开customErrors看异常再按这个顺序检查。6. 二次开发最值得先做的三件事Web API移动端、报表提速和多单位换算这三个方向不改变原有录单逻辑但能让老ERP源码在2025年继续用下去。6.1 给老ERP加登录接口用一般处理程序返回JSON想接入扫码枪或Vue3后台管理系统最省事的是在Web项目里新增一个handler.ashx在ProcessRequest里写登录校验返回JSONpublic void ProcessRequest(HttpContext context) { string user context.Request.Form[username]; string pwd context.Request.Form[password]; // 去用户表校验 bool ok new UserBll().CheckLogin(user, pwd); var result new { ok ok, token Guid.NewGuid().ToString(N) }; context.Response.ContentType application/json; context.Response.Write(JsonConvert.SerializeObject(result)); }说明POST请求密码建议先用MD5/SHA256加盐再比对不要明文。这个ashx不需要Session移动端每次请求带token。6.2 把库存汇总报表写成UNION ALL查询从分钟级降到秒级很多老ERP的销售报表是“先查明细在页面循环汇总”数据一多就卡。改成直接在数据库按天汇总SELECT CONVERT(varchar, CreateTime, 112) AS BillDate, COUNT(*) AS BillCount, SUM(TotalAmount) AS TotalAmount FROM SaleOrder WHERE CreateTime start AND CreateTime end GROUP BY CONVERT(varchar, CreateTime, 112) ORDER BY BillDate;说明这是典型的按时间分区汇总。一定要用CreateTime end不是避免重复统计。如果数据量继续涨再加一个“每日汇总表”定时刷新应用层只读汇总表。6.3 多单位换算不要改主表字段加一张换算表商品存在箱、瓶、件等不同单位直接在Product表加“单位换算率”字段的做法遇到一商品多单位就乱了。建议加独立换算表字段说明ProductId商品FromUnit原单位如“箱”ToUnit目标单位如“瓶”Factor1箱12瓶Factor12单据里记录数量单位保存时通过Factor换算成基础单位瓶去扣库存。这样报表显示可以灵活换单位库存永不以“箱”为唯一标准。这三件事做完老源码就不再是一个焊死的黑匣子而是能接手机、能快速出报表、能应对多单位业务的底座。我自己吃过最大的亏就是改代码前没先备份数据库改完成本算法后库存对不上加了三天班。从那以后“先备份、后动手、最后对流水”成了铁律。希望帮到你。本文还有配套的精品资源点击获取
返回列表