吉特倉儲管理系統簡單版開源也有一段時間了,獲得了衆多的開發者和軟件開發企業的諮詢和青睞,在此期間也經歷了版權糾紛等問題,反而到如今好像也不是版權糾紛的問題了,軟件著做權這個東西自己就很難以區分, 通過上次這麼一鬧以後賣源代碼的網站反而愈來愈多了,實在是使人防不慎防,因爲工做也就懶得去搭理這些東西了,就跟朋友說的我這是自找難受。因爲我的工做時間的問題,有些技術方面的問題實在很差一一解答,今天寫一篇博文總結一下各位所問道的問題。css
一. 哪裏修改數據鏈接html
這個是全部開發者中問的最多的問題,基本上加我QQ問我問題的基本也就是這個了。數據庫配置不是在web.config 中, 請各位不要被web.config中的鏈接誤導了,這是因爲新建項目自動生成的代碼。 數據庫配置文件路徑:前端
\Git.Storage.Web\Configs\Data\Database.config 如下是數據庫鏈接代碼,其中database 節點中的name=「JooWMS」 不能隨意修改, 這個對應映射到實體匹配關係,通常狀況狀況我設置爲了與最初數據庫名相同。
jquery
<?xml version="1.0" encoding="utf-8" ?> <databaseList> <database name="JooWMS"> <connectionString>Server=127.0.0.1;database=JooWMS;user id=sa;Password=000000</connectionString> </database> </databaseList>
二. 編譯不經過git
若是遇到編譯不經過的能夠先查看各個項目中dll引用是否有警告,若是遇到黃色dll引用警告則是dll文件丟失。 解決辦法是找到相應的dll從新添加引用或使用nuget從新下載github
三. 實體爲何使用partial關鍵字web
[TableAttribute(DbName = "JooWMS", Name = "OutStoDetail", PrimaryKeyName = "ID", IsInternal = false)] public partial class OutStoDetailEntity : BaseEntity { public OutStoDetailEntity() { } [DataMapping(ColumnName = "ID", DbType = DbType.Int32, Length = 4, CanNull = false, DefaultValue = null, PrimaryKey = true, AutoIncrement = true, IsMap = true)] public Int32 ID { get; set; } public OutStoDetailEntity IncludeID(bool flag) { if (flag && !this.ColumnList.Contains("ID")) { this.ColumnList.Add("ID"); } return this; } [DataMapping(ColumnName = "SnNum", DbType = DbType.String, Length = 50, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string SnNum { get; set; } public OutStoDetailEntity IncludeSnNum(bool flag) { if (flag && !this.ColumnList.Contains("SnNum")) { this.ColumnList.Add("SnNum"); } return this; } [DataMapping(ColumnName = "OrderNum", DbType = DbType.String, Length = 50, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string OrderNum { get; set; } public OutStoDetailEntity IncludeOrderNum(bool flag) { if (flag && !this.ColumnList.Contains("OrderNum")) { this.ColumnList.Add("OrderNum"); } return this; } [DataMapping(ColumnName = "ProductName", DbType = DbType.String, Length = 200, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string ProductName { get; set; } public OutStoDetailEntity IncludeProductName(bool flag) { if (flag && !this.ColumnList.Contains("ProductName")) { this.ColumnList.Add("ProductName"); } return this; } [DataMapping(ColumnName = "BarCode", DbType = DbType.String, Length = 50, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string BarCode { get; set; } public OutStoDetailEntity IncludeBarCode(bool flag) { if (flag && !this.ColumnList.Contains("BarCode")) { this.ColumnList.Add("BarCode"); } return this; } [DataMapping(ColumnName = "ProductNum", DbType = DbType.String, Length = 50, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string ProductNum { get; set; } public OutStoDetailEntity IncludeProductNum(bool flag) { if (flag && !this.ColumnList.Contains("ProductNum")) { this.ColumnList.Add("ProductNum"); } return this; } [DataMapping(ColumnName = "BatchNum", DbType = DbType.String, Length = 100, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string BatchNum { get; set; } public OutStoDetailEntity IncludeBatchNum(bool flag) { if (flag && !this.ColumnList.Contains("BatchNum")) { this.ColumnList.Add("BatchNum"); } return this; } [DataMapping(ColumnName = "LocalNum", DbType = DbType.String, Length = 50, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string LocalNum { get; set; } public OutStoDetailEntity IncludeLocalNum(bool flag) { if (flag && !this.ColumnList.Contains("LocalNum")) { this.ColumnList.Add("LocalNum"); } return this; } [DataMapping(ColumnName = "StorageNum", DbType = DbType.String, Length = 50, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string StorageNum { get; set; } public OutStoDetailEntity IncludeStorageNum(bool flag) { if (flag && !this.ColumnList.Contains("StorageNum")) { this.ColumnList.Add("StorageNum"); } return this; } [DataMapping(ColumnName = "Num", DbType = DbType.Double, Length = 8, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public double Num { get; set; } public OutStoDetailEntity IncludeNum(bool flag) { if (flag && !this.ColumnList.Contains("Num")) { this.ColumnList.Add("Num"); } return this; } [DataMapping(ColumnName = "IsPick", DbType = DbType.Int32, Length = 4, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public Int32 IsPick { get; set; } public OutStoDetailEntity IncludeIsPick(bool flag) { if (flag && !this.ColumnList.Contains("IsPick")) { this.ColumnList.Add("IsPick"); } return this; } [DataMapping(ColumnName = "RealNum", DbType = DbType.Double, Length = 8, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public double RealNum { get; set; } public OutStoDetailEntity IncludeRealNum(bool flag) { if (flag && !this.ColumnList.Contains("RealNum")) { this.ColumnList.Add("RealNum"); } return this; } [DataMapping(ColumnName = "OutPrice", DbType = DbType.Double, Length = 8, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public double OutPrice { get; set; } public OutStoDetailEntity IncludeOutPrice(bool flag) { if (flag && !this.ColumnList.Contains("OutPrice")) { this.ColumnList.Add("OutPrice"); } return this; } [DataMapping(ColumnName = "Amount", DbType = DbType.Double, Length = 8, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public double Amount { get; set; } public OutStoDetailEntity IncludeAmount(bool flag) { if (flag && !this.ColumnList.Contains("Amount")) { this.ColumnList.Add("Amount"); } return this; } [DataMapping(ColumnName = "ContractOrder", DbType = DbType.String, Length = 50, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string ContractOrder { get; set; } public OutStoDetailEntity IncludeContractOrder(bool flag) { if (flag && !this.ColumnList.Contains("ContractOrder")) { this.ColumnList.Add("ContractOrder"); } return this; } [DataMapping(ColumnName = "ContractSn", DbType = DbType.String, Length = 50, CanNull = true, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public string ContractSn { get; set; } public OutStoDetailEntity IncludeContractSn(bool flag) { if (flag && !this.ColumnList.Contains("ContractSn")) { this.ColumnList.Add("ContractSn"); } return this; } [DataMapping(ColumnName = "CreateTime", DbType = DbType.DateTime, Length = 8, CanNull = false, DefaultValue = null, PrimaryKey = false, AutoIncrement = false, IsMap = true)] public DateTime CreateTime { get; set; } public OutStoDetailEntity IncludeCreateTime(bool flag) { if (flag && !this.ColumnList.Contains("CreateTime")) { this.ColumnList.Add("CreateTime"); } return this; } }
以上是項目中截取的代碼, 定義了出庫單的實體對象,使用partial 關鍵字,以上代碼是Git.Framework.ORM 中實體映射類,在這個項目中業務模型類與數據庫模型類是公用的,因此在這個類上會擴展出來不少其餘的屬性出來。數據庫
public partial class OutStoDetailEntity { /// <summary> /// 產品規格 /// </summary> public string Size { get; set; } /// <summary> /// 庫位名稱 /// </summary> public string LocalName { get; set; } /// <summary> /// 用於退貨臨時數據變量,已經退貨數量 /// </summary> public double BackNum { get; set; } /// <summary> /// 數量 臨時變量 /// </summary> public double Qty { get; set; } }
以上就是擴展出來的輔助字段,能夠用於業務模型對象以及數據傳輸對象【我是偷懶了,業務模型,數據模型,數據傳輸模型我公用了一個類】。目前衆多開發者受DDD領域驅動開發思想的影響,定義了衆多的模型, 我認可我是爲了偷懶減小代碼量因此公用了。bootstrap
四. 數據庫操做好像不是EF緩存
public override List<InStorageEntity> GetList(InStorageEntity entity, ref PageInfo pageInfo) { entity.IncludeAll(); entity.Where(a => a.IsDelete == (int)EIsDelete.NotDelete); entity.OrderBy(a => a.ID, EOrderBy.DESC); AdminEntity admin = new AdminEntity(); admin.Include(a => new { CreateUserName = a.UserName }); entity.Left<AdminEntity>(admin, new Params<string, string>() { Item1 = "CreateUser", Item2 = "UserCode" }); int rowCount = 0; List<InStorageEntity> listResult = this.InStorage.GetList(entity, pageInfo.PageSize, pageInfo.PageIndex, out rowCount); pageInfo.RowCount = rowCount; return listResult; }
上面一段代碼是鏈接查詢數據庫,查詢了兩張表。而且有相應的查詢條件,使用了表達式會讓人誤覺得是EF,這個裏面不是使用的EF操做數據庫,本人對EF瞭解不夠深,也不太喜歡使用EF,這是一個基於微軟企業庫的ORM框架,由本人我的開發,由於不夠足夠的優秀因此在網上也就不出名,基本也就我我的項目使用一下。既然很差爲何還要用, 緣由很簡單 順手,開發項目快,並且基本趨於穩定。
關於這個ORM框架使用的相關文章: 《Git.Framework.Orm 框架使用文章彙總》 http://www.cnblogs.com/qingyuan/category/239086.html
五. 爲何不使用EF
1. EF 我的使用的太少,沒有深刻的去學習過EF, 有坑不能去解決
2. Git.Framework.Orm 是根據本身平時項目中遇到的問題總結下來編寫的。好比指定修改某個字段,查詢某些指定字段(數據權限控制),查詢字段直接映射業務模型,支持最直接的SQL語句,底層是ADO.NET(基於微軟企業庫)
3. 本身寫的東西用起來天然以爲舒服不少,本身的習慣來。
4. 除了使用對象映射還可使用配置文件來配置SQL語句(用於複雜的SQL語句,ORM很難處理複雜的SQL語句)
5. 定義了一套完整的數據庫操做方法, 支持存儲過程對應映射,用法和ADO.NET同樣
Proc_AuditeInStorageEntity auditeEntity = new Proc_AuditeInStorageEntity(); auditeEntity.OrderNum = entity.OrderNum; auditeEntity.Status = entity.Status; auditeEntity.AuditUser = entity.AuditUser; auditeEntity.Reason = entity.Reason; auditeEntity.OperateType = entity.OperateType; auditeEntity.EquipmentNum = entity.EquipmentNum; auditeEntity.EquipmentCode = entity.EquipmentCode; auditeEntity.Remark = entity.Remark; int line = this.Proc_AuditeInStorage.ExecuteNonQuery(auditeEntity);
<dataCommand name="Common.GetProceParam" database="JooWMS" commandType="Text"> <commandText> <![CDATA[ SELECT [SPECIFIC_CATALOG],[SPECIFIC_NAME],[ORDINAL_POSITION],[PARAMETER_MODE],[PARAMETER_NAME],[DATA_TYPE],[CHARACTER_MAXIMUM_LENGTH] FROM [INFORMATION_SCHEMA].[PARAMETERS] WHERE [SPECIFIC_NAME]=@SPECIFIC_NAME ]]> </commandText> <parameters> <param name="@SPECIFIC_NAME" dbType="String" direction="Input"/> </parameters> </dataCommand>
public List<ProceMetadata> GetMetadataList(string argProceName) { DataCommand command = DataCommandManager.GetDataCommand("Common.GetProceParam"); command.SetParameterValue("@SPECIFIC_NAME", argProceName); List<ProceMetadata> list = command.ExecuteEntityList<ProceMetadata>(); return list; }
六. 如何加載的CSS JS 文件
在加載CSS JS等文件的時候和傳統的方式沒有什麼區別,只是在頁面生成的時候作了一下處理。項目中的全部CSS 以及JS都是經過配置來加載的
配置路徑:\gitwms\Git.Storage.Web\Configs\File\File.config
<?xml version="1.0" encoding="utf-8"?> <Configs> <file name="CSS.bootstrap"><![CDATA[/Theme/plugins/bootstrap/css/bootstrap.css]]></file> <file name="CSS.font-awesome"><![CDATA[/Theme/plugins/font-awesome/css/font-awesome.css]]></file> <file name="CSS.style"><![CDATA[/Theme/css/style.css]]></file> <file name="CSS.style-responsive"><![CDATA[/Theme/css/style-responsive.css]]></file> <file name="CSS.default"><![CDATA[/Theme/css/themes/default.css]]></file> <file name="CSS.jbox"><![CDATA[/Theme/plugins/jbox-v2.3/jBox/Skins/Gray/jbox.css]]></file> <file name="CSS.autocomplete"><![CDATA[/Theme/plugins/jquery-autocomplete3.2.2/jquery.autocomplete.css]]></file> <file name="CSS.Error"><![CDATA[/Theme/css/pages/error.css]]></file> <file name="CSS.metro"><![CDATA[/Theme/plugins/bootstrap/css/style-metro.css]]></file> <!--公用JS組件--> <file name="Js.Enum"><![CDATA[/Common/Js]]></file> <file name="Js.Jquery"><![CDATA[/Theme/plugins/jquery-1.8.3.min.js]]></file> <file name="Js.bootstrap"><![CDATA[/Theme/plugins/bootstrap/js/bootstrap.min.js]]></file> <file name="Js.jBox"><![CDATA[/Theme/plugins/jbox-v2.3/jBox/jquery.jBox-2.3.min.js]]></file> <file name="Js.autocomplete"><![CDATA[/Theme/plugins/jquery-autocomplete3.2.2/jquery.autocomplete.js]]></file> <file name="Js.WdatePicker"><![CDATA[/Theme/plugins/My97DatePicker/WdatePicker.js]]></file> <file name="Js.Common"><![CDATA[/Theme/customer/Git.Framework.Common.js]]></file> <file name="Js.UICommon"><![CDATA[/Theme/customer/Git.Framework.UICommon.js]]></file> <file name="Js.Uploader"><![CDATA[/Theme/customer/jquery.jUploader-1.01.min.js]]></file> <file name="Js.Git.Framework.Sequence"><![CDATA[/Theme/customer/Git.Framework.Sequence.js]]></file> <!--用戶管理--> <file name="Js.Git.Storage.User"><![CDATA[/Theme/customer/User/Git.Storage.User.js]]></file> <!--角色管理--> <file name="Js.Git.Storage.Role"><![CDATA[/Theme/customer/User/Git.Storage.Role.js]]></file> <!--菜單管理--> <file name="Js.Git.Storage.Menu"><![CDATA[/Theme/customer/User/Git.Storage.Menu.js]]></file> <!--部門--> <file name="Js.Git.Storage.Depart"><![CDATA[/Theme/customer/Department/Git.Storage.Depart.js]]></file> <!--供應商--> <file name="Js.Git.Storage.Supplier"><![CDATA[/Theme/customer/Client/Git.Storage.Supplier.js]]></file> <!--客戶管理--> <file name="Js.Git.Storage.Client"><![CDATA[/Theme/customer/Client/Git.Storage.Client.js]]></file> <!--設備管理--> <file name="Js.Git.Storage.Equipment"><![CDATA[/Theme/customer/Storage/Git.Storage.Equipment.js]]></file> <!--倉庫管理--> <file name="Js.Git.Storage.Storage"><![CDATA[/Theme/customer/Storage/Git.Storage.Storage.js]]></file> <!--庫位管理--> <file name="Js.Git.Storage.Location"><![CDATA[/Theme/customer/Storage/Git.Storage.Location.js]]></file> <!--初始化產品庫存--> <file name="Js.Git.Storage.LocalProduct"><![CDATA[/Theme/customer/Storage/Git.Storage.LocalProduct.js]]></file> <!--計量單位--> <file name="Js.Git.Storage.Measure"><![CDATA[/Theme/customer/Storage/Git.Storage.Measure.js]]></file> <!--產品管理--> <file name="Js.Git.Storage.Goods"><![CDATA[/Theme/customer/Product/Git.Storage.Goods.js]]></file> <!--訂單管理--> <file name="Js.Git.Storage.OrderManage"><![CDATA[/Theme/customer/OrderManage/Git.Storage.OrderManage.js]]></file> <!--產品入庫管理列表--> <file name="Js.Git.Storage.ProductInOrder"><![CDATA[/Theme/customer/InStorage/Git.Storage.ProductInOrder.js]]></file> <!--產品出庫管理列表--> <file name="Js.Git.Storage.ProductOutOrder"><![CDATA[/Theme/customer/OutStorage/Git.Storage.ProductOutOrder.js]]></file> <!--產品報損管理列表--> <file name="Js.Git.Storage.ProductBadOrder"><![CDATA[/Theme/customer/Bad/Git.Storage.ProductBadOrder.js]]></file> <!--產品移庫管理列表--> <file name="Js.Git.Storage.MoveOrder"><![CDATA[/Theme/customer/Move/Git.Storage.MoveOrder.js]]></file> <!--產品盤點管理列表--> <file name="Js.Git.Storage.CheckOrder"><![CDATA[/Theme/customer/Check/Git.Storage.CheckOrder.js]]></file> <!--產品退貨管理列表--> <file name="Js.Git.Storage.ReturnOrder"><![CDATA[/Theme/customer/Returns/Git.Storage.ReturnOrder.js]]></file> <!--*******************************************報表***************************************************************--> <!--產品在線庫存報表--> <file name="Js.Git.Storage.ProductReport"><![CDATA[/Theme/customer/Report/Git.Storage.ProductReport.js]]></file> <!--產品出入庫報表--> <file name="Js.Git.Storage.ProductInOutReport"><![CDATA[/Theme/customer/Report/Git.Storage.ProductInOutReport.js]]></file> <!--入庫報表--> <file name="Js.Git.Storage.InStorageReport"><![CDATA[/Theme/customer/Report/Git.Storage.InStorageReport.js]]></file> <!--出庫報表--> <file name="Js.Git.Storage.OutStorageReport"><![CDATA[/Theme/customer/Report/Git.Storage.OutStorageReport.js]]></file> <!--客戶報表--> <file name="Js.Git.Storage.CustomerReport"><![CDATA[/Theme/customer/Report/Git.Storage.CustomerReport.js]]></file> <!--供應商報表--> <file name="Js.Git.Storage.SupplierReport"><![CDATA[/Theme/customer/Report/Git.Storage.SupplierReport.js]]></file> <!--庫存清單報表--> <file name="Js.Git.Storage.StockBillReport"><![CDATA[/Theme/customer/Report/Git.Storage.StockBillReport.js]]></file> <!--報損報表--> <file name="Js.Git.Storage.BadReport"><![CDATA[/Theme/customer/Report/Git.Storage.BadReport.js]]></file> <!--退貨報表--> <file name="Js.Git.Storage.ReturnReport"><![CDATA[/Theme/customer/Report/Git.Storage.ReturnReport.js]]></file> <!--臺賬報表--> <file name="Js.Git.Storage.InventoryReport"><![CDATA[/Theme/customer/Report/Git.Storage.InventoryReport.js]]></file> <!--ampie報表組件--> <file name="Js.Swfobject"><![CDATA[/Theme/plugins/ampie/swfobject.js]]></file> <!--報表管理JS--> <file name="Js.Git.Storage.ManagerReport"><![CDATA[/Theme/customer/Report/Git.Storage.ManagerReport.js]]></file> </Configs>
<?xml version="1.0" encoding="utf-8"?> <Groups> <!--錯誤友好提示界面--> <group name="Home.Error"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.Error</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Uploader</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.User</file> </group> <!--用戶用戶列表--> <group name="Home.UserList"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Uploader</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.User</file> </group> <!--序號管理--> <group name="Home.Sequence"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.WdatePicker</file> <file>File.Js.Enum</file> <file>File.Js.Uploader</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Framework.Sequence</file> </group> <!--用於角色列表--> <group name="Home.RoleList"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Role</file> </group> <!--用於部門管理--> <group name="Home.DepartList"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Depart</file> </group> <!--菜單管理--> <group name="Home.Menu"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Menu</file> </group> <!--用於供應商管理--> <group name="Client.Supplier.Index"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.Supplier</file> </group> <!--用於客戶管理--> <group name="Client.Customer.Index"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.Client</file> </group> <!--用於設備管理--> <group name="Storage.Equipment.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Equipment</file> </group> <!--用於倉庫管理--> <group name="Storage.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Storage</file> </group> <!--用於庫位管理--> <group name="Storage.Location.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Location</file> </group> <!--計量單位管理--> <group name="Storage.Measure.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.Measure</file> </group> <!--用於產品管理--> <group name="Product.Goods.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.autocomplete</file> <file>File.Js.Git.Storage.Goods</file> </group> <!--初始化產品庫存--> <group name="Storage.LocalProduct.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.LocalProduct</file> </group> <!--用於訂單管理--> <group name="Order.OrderManage.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Uploader</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.OrderManage</file> </group> <!--用於產品入庫管理--> <group name="Product.ProductInOrder.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.ProductInOrder</file> </group> <!--用於產品出庫管理--> <group name="Product.ProductOutOrder.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.ProductOutOrder</file> </group> <!--用於報損管理--> <group name="Product.ProductBad.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.ProductBadOrder</file> </group> <!--用於移庫管理--> <group name="Product.ProductMove.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.MoveOrder</file> </group> <!--用於盤點管理--> <group name="Product.ProductCheck.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Uploader</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.CheckOrder</file> </group> <!--用於退貨管理--> <group name="Product.ProductReturns.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.CSS.autocomplete</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.autocomplete</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Git.Storage.ReturnOrder</file> </group> <!--******************************************************報表***********************************************************--> <!--用於產品在線庫存報表--> <group name="Product.Report.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.ProductReport</file> </group> <!--用於產品出入庫報表--> <group name="Product.InOutReport.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.ProductInOutReport</file> </group> <!--用於入庫報表--> <group name="Product.InStorageReport.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.InStorageReport</file> </group> <!--用於客戶報表--> <group name="Product.CustomerReport.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.CustomerReport</file> </group> <!--用於供應商報表--> <group name="Product.SupplierReport.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.SupplierReport</file> </group> <!--用於出庫報表--> <group name="Product.OutStorageReport.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.OutStorageReport</file> </group> <!--庫存清單報表--> <group name="StockBill.Report.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.StockBillReport</file> </group> <!--報損報表--> <group name="BadReport.Report.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.BadReport</file> </group> <!--退貨報表--> <group name="ReturnReport.Report.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Swfobject</file> <file>File.Js.Git.Storage.ReturnReport</file> </group> <!--臺賬報表--> <group name="InventoryReport.Report.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.InventoryReport</file> </group> <!--報表管理--> <group name="Report.Manager.List"> <file>File.CSS.bootstrap</file> <file>File.CSS.font-awesome</file> <file>File.CSS.style</file> <file>File.CSS.style-responsive</file> <file>File.CSS.default</file> <file>File.CSS.jbox</file> <file>File.Js.Jquery</file> <file>File.Js.bootstrap</file> <file>File.Js.jBox</file> <file>File.Js.Enum</file> <file>File.Js.WdatePicker</file> <file>File.Js.Common</file> <file>File.Js.UICommon</file> <file>File.Js.Uploader</file> <file>File.Js.Git.Storage.ManagerReport</file> </group> </Groups>
<?xml version="1.0" encoding="utf-8"?> <PageConfigs> <!--員工管理頁面--> <page name="Home.UserList" path="/Home/UserList"> <group>FileGroup.Home.UserList</group> <seo>Seo.Index</seo> </page> <!--添加員工--> <page name="Home.AddUser" path="/Home/AddUser"> <group>FileGroup.Home.UserList</group> <seo>Seo.Index</seo> </page> <!--帳戶設置頁面--> <page name="Home.AccountSetting" path="/Home/AccountSetting"> <group>FileGroup.Home.UserList</group> <seo>Seo.Index</seo> </page> <!--角色管理頁面--> <page name="Home.RoleList" path="/Home/RoleList"> <group>FileGroup.Home.RoleList</group> <seo>Seo.Index</seo> </page> <!--部門管理頁面--> <page name="Home.DepartList" path="/Home/DepartList"> <group>FileGroup.Home.DepartList</group> <seo>Seo.Index</seo> </page> <!--菜單管理--> <page name="Res.Index" path="/Res/Index"> <group>FileGroup.Home.Menu</group> <seo>Seo.Index</seo> </page> <!--權限分配--> <page name="Res.Power" path="/Res/Power"> <group>FileGroup.Home.Menu</group> <seo>Seo.Index</seo> </page> <!--系統日誌--> <page name="Res.SysLog" path="/Res/SysLog"> <group>FileGroup.Home.Menu</group> <seo>Seo.Index</seo> </page> <!--錯誤友好提示界面--> <page name="Home.Error" path="/Home/Error"> <group>FileGroup.Home.Error</group> <seo>Seo.Index</seo> </page> <!--首頁--> <page name="Home.Welcome" path="/Home/Welcome"> <group>FileGroup.Home.UserList</group> <seo>Seo.Index</seo> </page> <!--序號管理--> <page name="Home.Sequence" path="/Home/Sequence"> <group>FileGroup.Home.Sequence</group> <seo>Seo.Index</seo> </page> <!--標識符管理--> <page name="Home.SN" path="/Home/SN"> <group>FileGroup.Home.Sequence</group> <seo>Seo.Index</seo> </page> </PageConfigs>
看起來好複雜的樣子,三級配置加載CSS JS 以及頁面title等信息。頁面中會有代碼去解析這些配置文件。 會有人問這有毛線用,的確沒有任何毛線用,然並卵。 這些配置文件都是依賴形式的,都緩存與系統中,當你文件有修改的時候會自動失效配置文件緩存而後從新讀取新文件,目的就是爲了避免重啓服務。 因此你認爲他有用就有用,你認爲畫蛇添足就是畫蛇添足。此舉還帶來了一個嚴重的問題,就是不熟悉此結構的人在開發過程當中配置JS比較難以上手。
七. 用的什麼方式打印
目前開源的代碼中使用的FastReport做爲報表設計工具以及打印工具, 以前也是用過lodop打印,因此項目中仍然存在lodop的殘存文件。使用報表設計器看起來高大上,這在衆多的開發者眼中是這樣的,可是對於客戶來講並非這樣的,客戶其實至關比較難以上手設計一個報表打印,覺得他要去了解這個系統的數據結構,這是一個很是痛苦的事情。 爲何使用報表設計器,是由於以前我在開發報表的時候一個報表就要去開發一個頁面,使用報表設計器能夠簡化這個過程。 以上兩個組件都是收費的,因此酌情考慮。
八. 數據庫設計
認真看過代碼的人都應該看過數據庫結構,在此以前有人提出個人數據庫設計很是爛,不適合初學者學習。這裏我先不否定這個問題,我也不說這個項目有多麼的優秀。 在此項目的設計過程當中,數據庫存在一個較大的問題,那就是表中重複的字段比較多。
if exists (select * from sysobjects where name='InStorDetail') drop table InStorDetail go create table InStorDetail ( ID int not null identity(1,1) primary key , --主鍵編號 SnNum varchar(50) not null , --惟一編號 OrderSnNum varchar(50) not null , --入庫單惟一編號 ProductName nvarchar(100) , --產品名稱 BarCode varchar(50) , --條碼編號 ProductNum varchar(50) not null , --產品惟一編碼 BatchNum nvarchar(50) , --生產批次 Num float not null , --入庫數量 IsPick int not null , --是否審覈 RealNum float not null , --實際數量 InPrice float not null , --入庫單價 Amount float not null , --金額 ContractOrder varchar(50) , --關聯單號 CreateTime datetime not null , --建立時間 LocalNum varchar(50) , --庫位編號 StorageNum varchar(50) , --倉庫編號 CompanyID varchar(50) not null , --公司惟一編碼 ) go
就好比說上面這個表結構,其中產品的相關屬性咱們能夠經過ProductNum 惟一值來關聯查詢出ProductName,BarCode 等信息, 數據庫設計範式的問題。在衆多的表中重複的字段很是之多,並不是本人不懂數據庫設計範式,具體狀況具體來. 這次這樣設計是爲了減小關聯查詢的問題,避免查詢的過程當中關聯多個表。 不要問我爲何,程序寫多了你就明白真理並非指明燈,理論有時候也很坑人。若是以爲此處學習是誤導,那就請跳過此處問題
九. 單據的設計
在倉庫系統中最多的也就是單據了, 在這個系統中單據基本分爲主從關係。在前期的開發中,系統中涉及的單據很是之多,好比入庫單就分爲:採購入庫單,銷售退貨入庫單,生產入庫單,退還入庫單等等,由於考慮到要兼容各類業務場景,因此定義了很是之多的單據,數據庫中的主從表也很是之多。在後期的改版中從支付寶的訂單處理中獲得一些啓發,在總體上定義了單據的概念,單據操做的方法也固定在特定範圍內。
public abstract partial class Bill<T, V> : DataFactory where T : BaseEntity where V : BaseEntity { /// <summary> /// 定義日誌類 /// </summary> protected Log log = Log.Instance(typeof(T)); /// <summary> /// 建立單據 /// </summary> /// <param name="entity"></param> /// <param name="list"></param> /// <returns></returns> public abstract string Create(T entity, List<V> list); /// <summary> /// 取消單據 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string Cancel(T entity); /// <summary> /// 刪除單據 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string Delete(T entity); /// <summary> /// 審覈單據 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string Audite(T entity); /// <summary> /// 打印單據 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string Print(T entity); /// <summary> /// 查詢單據 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract T GetOrder(T entity); /// <summary> /// 得到單據詳細信息 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract List<V> GetOrderDetail(V entity); /// <summary> /// 查詢單據分頁 /// </summary> /// <param name="entity"></param> /// <param name="pageInfo"></param> /// <returns></returns> public abstract List<T> GetList(T entity, ref PageInfo pageInfo); /// <summary> /// 查詢單據詳細數據分頁 /// </summary> /// <param name="entity"></param> /// <param name="pageInfo"></param> /// <returns></returns> public abstract List<V> GetDetailList(V entity, ref PageInfo pageInfo); /// <summary> /// 編輯單據信息 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string EditOrder(T entity); /// <summary> /// 編輯單據詳細信息 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract string EditDetail(V entity); /// <summary> /// 編輯入庫單 /// </summary> /// <param name="entity"></param> /// <param name="list"></param> /// <returns></returns> public abstract string EditOrder(T entity, List<V> list); /// <summary> /// 得到訂單數量 /// </summary> /// <param name="entity"></param> /// <returns></returns> public abstract int GetCount(T entity); /// <summary> /// 得到打印單據的數據源 /// </summary> /// <param name="argOrderNum"></param> /// <returns></returns> public abstract DataSet GetPrint(string argOrderNum); }
以上是單據模型的抽象,全部實際的單據都要實現此抽象類,同時也合併了不一樣類型的入庫爲入庫單. 入庫單在整體上上是一個概念,若是要去擴展入庫單到具體的業務能夠再此基礎上去修改。因此在倉庫系統代碼中定義了幾個基本的單據:入庫單,出庫單,移庫單,報損單,盤點單,由於倉儲系統主要用於管理數量,而以上操做都是直接影響庫存數據的。
十. 前端頁面操做的顆粒性,一致性
本身曾在以往的軟件開發過程當中,不少動做都是連續進行的。 好比 列表中中刪除一行數據而後從新刷新列表數據。 以往開發的時候作法通常是發送一個刪除請求,而後同時返回刪除以後的新數據,在目前現有的系統開發中這種操做都被分解,好比上述過程分解爲兩個動做:(1) 發送請求刪除,返回刪除狀態 (2) 根據返回狀態再從新請求後臺列表數據, 也就是這個動做其實有兩個請求,在以往的時候我開發直接使用了一個http請求就處理掉了【不是批判這個處理方式的問題,目前系統開發中也有不少人是這樣處理的,不少人給出的理由多了一次請求】。 首先我這裏不是什麼特別高併發的系統, 多一次請求少一次請求也無所謂,其次這裏爲了保證任何操做動做的顆粒性,在處理權限上也是很不錯的。
然而單據是一個總體,因此不少時候回設計到一個多表操做的動做,這個時候必定要使用到事務,這個在技術上天然不用多說。有不少人提出了一個疑問,在各類單據處理的時候,好比選擇多個產品的時候,我選擇了產品數據是保存在哪裏的
在點擊新增產品按鈕的時候,而後選擇產品以後表格中加載數據,不少人到數據庫中去查找並無發現新增數據。這裏選擇產品數據也是保存到了服務端的緩存中【注意是服務端緩存中,而不是客戶端頁面中】, 也有不少人將數據緩存到客戶端的作法,有什麼優缺點在這裏不作過多的說明,業務型系統建議是保存到後臺中。這裏也有上面提到的顆粒操做, 表格中也有編輯以及刪除操做,每個動做都是拆分的,雖然看起來是連貫的。當產品肯定以後提交整個表單,包括表單頭部以及產品列表數據,使用事務一次性提交到數據庫。
十一. 更多的Controller 控制器
本項目使用的asp.net mvc,細心的應該能夠看出在Controller類上有點小小的不一樣, 一個模塊(單據類型的模塊)基本對應三個Controller,好比產品入庫:ProductManagerAjaxController , ProductAjaxController, ProductController , 這三個控制器整體控制着入庫單的全部操做,其中兩個是帶有Ajax的, 是的沒有錯。 ManagerAjaxController 基本是控制列表頁面的操做, AjaxController 控制數據的編輯錄入等,XController 基本就控制的試圖的顯示。
在整個系統中我將請求分爲了四大類: 主頁面控制(導航菜單出來的頁面), 頁面連接子頁(導航菜單指向頁面中的連接鏈出來的頁面,和上面一個優勢相似),對話框,Ajax 請求。 我不知道有沒有人跟我同樣作過相似的分類,就目前並且我以爲此種分類仍是比較好的,基本囊括BS開發頁面中的集中請求方式,雖然都是Http請求, 可是這個對於我在系統中的權限控制相當重要。
public class ProductAjaxController : AjaxPage { /// <summary> /// 新建入庫單 /// 返回值說明: /// 1001 : 請選擇要入庫的產品以及數量 /// </summary> /// <returns></returns> [LoginAjaxFilter] public ActionResult Create() { int InType = WebUtil.GetFormValue<int>("InType", 0); int ProductType = WebUtil.GetFormValue<int>("ProductType", 0); string ContractOrder = WebUtil.GetFormValue<string>("ContractOrder", string.Empty); string SupNum = WebUtil.GetFormValue<string>("SupNum", string.Empty); string SupName = WebUtil.GetFormValue<string>("SupName", string.Empty); string ContactName = WebUtil.GetFormValue<string>("ContactName", string.Empty); string Phone = WebUtil.GetFormValue<string>("Phone", string.Empty); DateTime OrderTime = WebUtil.GetFormValue<DateTime>("OrderTime", DateTime.Now); string Remark = WebUtil.GetFormValue<string>("Remark", string.Empty); InStorageEntity entity = new InStorageEntity(); entity.OrderNum = SequenceProvider.GetSequence(typeof(InStorageEntity)); entity.InType = InType; entity.ProductType = ProductType; entity.SupNum = SupNum; entity.SupName = SupName; entity.ContactName = ContactName; entity.Phone = Phone; entity.Address = ""; entity.ContractOrder = ContractOrder; entity.Status = (int)EAudite.Wait; entity.IsDelete = (int)EIsDelete.NotDelete; entity.OrderTime = OrderTime; entity.CreateTime = DateTime.Now; entity.CreateUser = this.LoginUserCode; entity.AuditUser = string.Empty; entity.AuditeTime = DateTime.MinValue; entity.PrintUser = string.Empty; entity.PrintTime = DateTime.MinValue; entity.Reason = string.Empty; entity.OperateType = (int)EOpType.PC; entity.EquipmentNum = string.Empty; entity.EquipmentCode = string.Empty; entity.Remark = Remark; entity.StorageNum = this.DefaultStore; List<InStorDetailEntity> list = Session[CacheKey.TEMPDATA_CACHE_INSTORDETAIL] as List<InStorDetailEntity>; if (list.IsNullOrEmpty()) { this.ReturnJson.AddProperty("Key", "1001"); this.ReturnJson.AddProperty("Value", "請選擇要入庫的產品以及數量"); return Content(this.ReturnJson.ToString()); } entity.Num = list.Sum(a => a.Num); entity.Amount = list.Sum(a => a.Amount); Bill<InStorageEntity, InStorDetailEntity> bill = new InStorageOrder(); string returnValue = bill.Create(entity, list); if (returnValue == EnumHelper.GetEnumDesc<EReturnStatus>(EReturnStatus.Success)) { Session[CacheKey.TEMPDATA_CACHE_INSTORDETAIL] = null; this.ReturnJson.AddProperty("Key", "1000"); this.ReturnJson.AddProperty("Value", "入庫單建立成功"); } return Content(this.ReturnJson.ToString()); } }
public class ProductController : MasterPage { /// <summary> /// 入庫單列表管理 /// </summary> /// <returns></returns> [LoginFilter] public ActionResult List() { ViewBag.InType = EnumHelper.GetOptions<EInType>(0, "請選擇入庫單類型"); ViewBag.ReportNum = ResourceManager.GetSettingEntity("InOrder_Template").Value; return View(); } }
以上兩個代碼就區分了基本的Get頁面請求以及Ajax請求, 在軟件開發過程當中我一直推崇的就是約定大於配置,說白了這全是他麼的套路,套路,套路。 我爲何要這麼定義,由於套路, 我熟悉套路因此我開發快。因此若是有心的同窗能夠參考一下此種作法
十二. 有沒有更高級的版本
在這個項目上諮詢的大部分都是軟件開發者, 有時候提的一些問題令我是作很差怎麼回答,技術問題,版權問題,讓我技術支持問題,高級版本問題,爲何開源,爲何不所有開源
(1) 以前有人找我買源碼,我問他的預算,他說要全部的源代碼包括能夠註冊軟件著做權的,預算幾千塊。 個人回答你本身找人去開發吧,還不用擔憂版權問題,想怎麼來就怎麼來
(2) "你寫的代碼太爛了,學習真的有難度,某個軟件就比你的好,就是他的代碼太貴了" , 通常這種問題也就技術人員提吧, 除非看本身的代碼不然看別人的代碼都是垃圾, 一句話個人代碼中沒有使用特別高深的技術,代碼質量也有限,我本身可以看懂。
(3) "我可不能夠跟你合做,你有產品我有客戶", 這個固然沒問題了,你們共同賺錢, 客戶作成了你拿60%的費用都不是問題, 請問你如今有多少有意向的客戶,回答:"我尚未取跑過客戶"
(4) 「咱們公司想用大家的這套系統,要可以支持二次開發」 , 絕不猶豫企業作倉庫軟件願意提供較高質量的技術支持以及業務方面的指導
(5) 「你這個好像不是完整代碼」 , 開源部分是從以往的項目中整理出來的,倉庫做業基本是完整可使用的,提供了數據結構 使用沒有任何問題,可是不要奢望我去給你解釋每一個字段是什麼含義,學習就得付出。
(6) 「我在淘寶上花了10塊錢買的你的源碼,技術支持留的你的聯繫方式」, 我再也不想回答這種問題
(7) "有沒有更高版本的倉庫系統",開源的版本定義爲V3.0 ,如今已經開發出來V4.0版本了, 對多倉庫,多企業,雲服務,採購,銷售,財務都有簡單的支持,而且也已經應到幾個企業中,後面不打算開源了,看着別人拿到淘寶上去賣源碼有點心疼
題外話: 若是有企業想合做,能夠受權源碼開發,提供技術支持。 不要問我爲何,套路。
十三. 能不能帶來收入
吉特倉儲管理系統從我接觸開始到如今已經差很少四年時間了,這個時間說長不長說短也不短了。 一個軟件堅持作四年估計也是比較難的,也就今年才稍微好點。 能不能賺錢,我能夠確定的告訴各位是能夠賺錢的, 8月份成交了兩個企業單, 雖然比不來什麼幾千萬的項目,也不可能幾十萬,可是在工做之餘帶來額外的收入這個數目仍是比較客觀的。
前不久給幾個開發的好友講解了一下吉特倉儲管理系統的快速開發問題,之前就是本身一我的在房間裏開發開發,這是第一次公開的給別人說倉庫系統的開發。我但願倉庫系統可以作的更好,功能更加的完善,在後續的過程當中服務更多的客戶。
打個小廣告: 吉特倉儲管理系統簡單版開源地址: https://github.com/hechenqingyuan/gitwms 倉庫系統交流羣:88718955, 142050808 , 我的QQ: 821865130 若是有意願合做和業務探討的客戶能夠聯繫我 15800466429
做者:情緣
出處:http://www.cnblogs.com/qingyuan/
關於做者:從事倉庫,生產軟件方面的開發,在項目管理以及企業經營方面尋求發展之路
版權聲明:本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
聯繫方式: 我的QQ 821865130 ; 倉儲技術QQ羣 88718955,142050808 ;
吉特倉儲管理系統 開源地址: https://github.com/hechenqingyuan/gitwms