吉特仓库管理系统- 基本问题解答

 

  吉特仓储管理系统简单版开源也有一段时间了,获得了众多的开发者和软件开发企业的咨询和青睐,在此期间也经历了版权纠纷等问题,反而到如今好像也不是版权纠纷的问题了,软件著做权这个东西自己就很难以区分, 通过上次这么一闹以后卖源代码的网站反而愈来愈多了,实在是使人防不慎防,因为工做也就懒得去搭理这些东西了,就跟朋友说的我这是自找难受。因为我的工做时间的问题,有些技术方面的问题实在很差一一解答,今天写一篇博文总结一下各位所问道的问题。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>
SQL语句配置执行

 

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>
CSS JS 文件的配置
<?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());
        }
}
Ajax请求操做实例
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

相关文章
相关标签/搜索