在此文开篇之处先特别申明,此文在有些人的眼中会有广告的嫌疑,可是本人不想将其做为一个广告宣传的文章,在此提到软件内容部分请你们予以谅解和包含,做为时间不算短的程序员给你们分享一些本身开发吉特仓储管理软件相关的经验和坑,固然还有一些本身从中获利的方式,不能说给你们指条明路吧,算是做为程序开发人的相互经验交流。javascript
此文原本想写在国庆假期以前的,可是那段时间公司事情恰好很忙,因此没有来得及写此文。当时要搞Solr搜索引擎,由于本身不熟悉java程序因此在弄得过程当中有些费力,并且本身自己也不是一心苦心专研程序技术的人,但我绝对是一位苦心专研程序的人,虽然最终也没有什么大的成果。去年公司没有干以后,一直到今年如今我一直在想为什么咱们公司会作不下去,就连一个小公司都作不下去,其实咱们也很努力,咱们也很拼命,创业之初一周基本上四天会睡在办公室,每日每夜的作项目,那个时候是有客户的,可是到了最后发现每一个项目都不赚钱,为何时间太长了,不能快速解决客户问题[这只是其中一个很小的缘由],当时肯定了公司的方向就是要作仓储物流制造方面的软件产品。虽然我知道这个行业竞争很大,不少人说如今的市场有不少成熟的产品,这个不说我也天然明白,每一个人都有本身的想法,也有本身针对的市场方向,咱们在此很少说。css
一. 深刻一个行业html
最开始作开发的时候涉及到过好多行业,汽车零配件,金融单位,游戏行业,房地产行业,一直作着感受最终除了会写代码好像啥也不会,一个行业的套路你都尚未弄清楚感受你就落伍了(主要是干个几年感受工资跟不上了,只能跳槽增长工资咯,其实我跳槽没有一次是加过工资的,由于我胆小,只要认为本身过得去就好了,最重要的是以为本身干的值)。不是每一个技术员均可以开公司的,可是不少技术员都给别人作过私活,感受工做之余赚点小钱仍是很不错的,在此以前我也干过感受挺牛逼的.其实后来我也作的少,我也去问过不少人他们基本一致的答案:私活真的是赚的辛苦钱,天天没日没夜的,真不如上班。 这个的确是如此的,我已人格保证, 因此如今刚出道的程序员们若是手上没有什么货的话,真的不要轻易去接什么私活。java
1. 你跳槽那么屡次,多少年以后你发现你比别人强在哪里?git
这个问题好容易戳人的心窝子,特别是作过外包的同窗感触确定很深,今天这个项目须要我那我不顾一切扑上去,下一个项目须要我被迫扑上去。国庆回家的时候,火车上三个湖南小伙,听聊天得知是干程序的,其中一人说我作过某某军工企业的什么软件,我作过某某银行的什么软件,我还作了某个***企业什么的软件, 其实我只是听听,我基本知道这个小伙是干外包项目的,而后还有一个携程的小伙,他们聊了不少我一直不说话,可是他们都谈到了一个问题就是这些年下来感受除了会写代码,好像就干不了其余的,若是换了一个行业或者一个项目组又好像从头开始了。程序员
其实这就是问题的所在,由于你在短时间内不断的在切换你不熟知的领域,你尚未足够的时间来深刻了解这个行业的特性,也就使得你不可以在这个行业成为专家,因此你最终的结果就是可替代性很强,程序员如今大把大把的,上海地铁上随便抓一大把,替换你分分钟的事情,就说携程招人和离职的速度来看就足以说明这个问题。在此以前我也有过相似的感觉,感受到头来啥啥都不是,我等天之愚钝之人不可能作到技术牛逼之人,发挥不了本身的智商。那就只能在某个小的领域专心作事,作精作强。github
以前我特别羡慕一个朋友,他是作销售的,其实他所作的事情远不是一个销售人员可以达到的了,他以前是作货架,自动门等销售的,一直作了十来年吧,后面我常常跟着他一块儿去跑客户,我说让他带我我见世面,到客户那边以后他所作的事情远不是销售给客户介绍产品,推荐价格。到了客户仓库他会给客户作专业的仓库规划测量,他随身带着卷尺,测距仪,黄胶带等等一系列东西,俨然就是一个工程师的范,事情作得很是的专业到位,可是我见他不多直接给客户推荐某个产品,而后还会给客户给出规划的图纸设计图。当时我非常惊呆,这个销售的确作的到位,后面我问他是否是学这个行业的,他说他历来没有学过这些,只是在这个行业一直作就慢慢的专业了。再后来我有认识了另一个作一样销售的销售员,他也就是一个普通的销售员了,我跟他去看客户现场他也就只知道拿着产品说明书给客户介绍产品了,差距天然不说,后面这位就没有干这一行了,我问他为何,他说这个行业赚不到钱。那个朋友如今上海儿女双全,有车有房,相信比通常的程序员要好不少的。后面他说本身作货架销售,在他们公司作了一个业绩全国第一,好像是这样的。总之给个人感受他作这个事"专业",他也给过我一个建议:“好好的干一行” 数据库
2. 你为何成为不了专家?json
前不久上海嘉定那边一个工厂的客户老板打电话我,说你好像好久没有到咱们公司来坐坐了,你啥时候有空到咱们公司来坐坐啊,咱们聊聊人生。其实这位老板年长我不少,为人很精明。我问他是否是软件出问题了,他说不是的,他说像找你聊聊仓库生产方面的事情。当他电话个人时候我第一个反应就是软件出问题了,后面聊下来他以为流程比软件更重要吧,他是想让我帮他们想一想如何优化生产流程以及仓库做业。其实我不太想搭理这个客户,具体缘由不说了.可是客户可以给我打电话我仍是挺高兴的,其实他大能够去找别人或者其余的供应商来处理这个事情。他说事情我一点就通,他们说的生产仓库问题我很快就可以知道他们说的什么问题,而且给出合理的建议,他们以为我很专业。 其实我不能自夸本身是专业,当时决定作了这个方面的事情以后,个人确花了很大的精力来了解这个行业的知识,包括现场实地考察。后端
什么是专家, 我我的以为就是在这个行业有资深经验, 专 就是专业, 家 很差怎么解释,反正画家,书法家等比较有威望吧,最关键的是可以在关键时刻关键点起到关键做用, 固然不能说咱们国家某某部门某某专家了,这种话不要多说。专家可以刻画到点子上,戳中要点一针见血,找出良方,这就是专家。专家除了苦学那就是经验积累,遇到的问题越多后面你可以解决问题的概率就越大,长此以往你就是专家了。其实如今不少作技术的今天学.NET,明天又是Java,再来讲PHP(拍黄片)是世界上最好的语言, 长此以往其实他也就是一个普通写代码的,干了10年仍是只能写浅显的代码。
二. 项目开发你为什么这么慢
我本身一句有一句调侃本身的话:"每一个人都说时间就是金钱,你的时间真的值钱么,若是在特定的时间内你没有创造价值那么你的时间就不值钱" 。 好像有点过度,但对于我本身来讲是有道理的
1. 为什么一个简单的进销存你都要作三个月
这是我当年遇到的很现实的问题,先不说价钱问题。别人一个月就能够上线运行,为什么你一个简单的进销存要作三个月,咱们仔细罗列这些功能:(1) 系统设置 (2) 用户管理 (3) 部门管理 (4) 角色管理 (4)产品管理 (6) 价格管理 (7) 客户管理 (8) 供应商管理 .....我实在不想说下去了,简单的进销存确实不止这些功能,在怎么简单你得让客户流程可以跑起来才行啊。
再从技术方面考虑: 这得有多少张表啊,数据库操做好多代码啊,还要设计前段UI,作的交互性好还要大量的JS,想一想这些工做量3个月真的一点很少。唉,为何我就没有一套能够复用的东西呢?
对的,由于你没有能够复用的东西,因此你慢,你项目进度不能快也就在情理之中了
2.怎么就没有公共组件
等你肯定好作一个行业软件的开发以后,技术体系基本肯定以后,开发仍是慢啊。我要弹出框,系统规划中没有这个组件,我要从网上找。 好多个页面要选择用户信息,弹出页面,第一个页面凑合着作吧,忍了,又来一个这样的页面需求,又忍了, 愈来愈多,忍无可忍,这种业务组件你为什么不封装成公共的呢。
; (function ($) { $.fn.ProductDialog = function (options) { var defaultOption = { data: {}, Mult: true, EventName: "dblclick", callBack: undefined }; defaultOption = $.extend(defaultOption, options); var DataServer={ Server: function () { var config = (function () { var URL_GetList = "/Storage/ProductAjax/GetList"; return { URL_GetList: URL_GetList }; })(); //数据操做服务 var dataServer = (function ($, config) { //查询分页列表 var GetList=function(data,callback){ $.gitAjax({ url: config.URL_GetList, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } return { GetList: GetList } })($, config); return dataServer; }, PageClick:function(PageIndex,PageSize){ $.jBox.tip("正在努力加载数据...","loading"); var Server=DataServer.Server(); var search={}; search["PageIndex"]=PageIndex; search["PageSize"]=PageSize; Server.GetList(search,function(result){ DataServer.SetTable(result); $.jBox.closeTip(); }); }, SetTable:function(result){ current.find("#tabInfo").DataTable({ destroy: true, data:result.Result, paging:false, searching:false, scrollX: false, bAutoWidth:false, bInfo:false, ordering:false, columns: [ { data: 'SnNum' ,render:function(data, type, full, meta){ return "<input type='checkbox' name='product_item' value='"+data+"' data-full='"+JSON.stringify(full)+"'/>"; }}, { data: 'BarCode'}, { data: 'ProductName',createdCell:function(td, cellData, rowData, row, col){ if(!git.IsEmpty(cellData) && cellData.length>10){ $(td).popover({container:"body",content:cellData,trigger:"hover",placement:"bottom",delay:{show:500}}); } },render:function(data,type,full,meat){ return git.GetStrSub(data,10); }}, { data: 'Size',render:function(data,type,full,meta){ return git.GetStrSub(data,10); },createdCell:function(td, cellData, rowData, row, col){ if(!git.IsEmpty(cellData) && cellData.length>10){ $(td).popover({container:"body",content:cellData,trigger:"hover",placement:"bottom",delay:{show:500}}); } }}, { data: 'CateName'}, { data: 'UnitName'}, { data: 'MaxNum'}, { data: 'MinNum'}, { data: 'AvgPrice'}, { data: 'Display',render:function(data,type,full,meta){ return git.GetStrSub(data,10); },createdCell:function(td, cellData, rowData, row, col){ if(!git.IsEmpty(cellData) && cellData.length>10){ $(td).popover({container:"body",content:cellData,trigger:"hover",placement:"bottom",delay:{show:500}}); } }} ], aoColumnDefs:[ { "sWidth": "15px", "aTargets": [0] } ], oLanguage:{ sEmptyTable:"没有查询到任何数据" } }); var pageInfo=result.PageInfo; if(pageInfo!=undefined){ current.find("#myMinPager").minpager({ pagenumber: pageInfo.PageIndex, recordCount: pageInfo.RowCount, pageSize: pageInfo.PageSize, buttonClickCallback: DataServer.PageClick }); } DataServer.BindEvent(); }, BindEvent:function(){ if(defaultOption.Mult){ current.find("#tabInfo").find("input[name='item_all']").click(function(event) { var flag=$(this).attr("checked"); if(flag){ current.find("#tabInfo").find("input[name='product_item']").attr("checked",true); }else{ current.find("#tabInfo").find("input[name='product_item']").attr("checked",false); } }); } else{ current.find("#tabInfo").find("input[name='item_all']").hide(); current.find("#tabInfo").find("input[name='product_item']").click(function(event) { current.find("#tabInfo").find("input[name='product_item']").attr('checked', false); $(this).attr("checked",true); }); } //搜索 current.find(".search").find('button[data-command="Search"]').click(function(event) { DataServer.PageClick(1,10); }); }, GetSelect:function(){ var list=[]; current.find("#tabInfo").find("input[name='product_item']").each(function(i,item){ var flag=$(item).attr("checked"); if(flag){ var value=$(item).attr("data-full"); list.push(JSON.parse(value)); } }); return list; } } var submit = function (v, h, f) { if (v == 1) { var list=DataServer.GetSelect(); if(list==undefined || list.length==0){ $.jBox.tip("请选择产品","warn"); return false; } if (defaultOption.callBack != undefined && typeof (defaultOption.callBack) == "function") { if(defaultOption.Mult){ defaultOption.callBack(list); }else{ defaultOption.callBack(list[0]); } } } }; $(this).bind(defaultOption.EventName, function () { $.jBox.open("get:/Storage/Product/Dialog", "选择产品", 850, 600, { buttons: { "选择": 1, "关闭": 2 }, submit: submit, loaded: function (h) { current=h; DataServer.PageClick(1,10); } }); }); }; })(jQuery);
相似于这种的组件,在项目中有大量使用,若是可以作到全局公共而且方便使用这就是极佳的。最终造成组件也是有发展历程的: 开始只是一个简单的额对话框显示表格而且选中产品,慢慢的又有更多的需求,好比要可以搜索,要可以分页,要支持多选以及单选等等,双几行可以自动选择等一系列问题。其实你作好了公共组件在后期的开发中也就省事了。
3. 代码的套路
10我的就有10种代码风格,这种相互改代码会让人崩溃,人员的离职,没有文档和注释的说明,字段和数据库的对应不起来,各类让人吐的问题。不要太多的花样,定义好套路,全部的代码必须遵循这种套路你会快不少,最关键的是找bug的速度回快不少。
/** * *财务管理-应收实收 * **/ var FinanceBillManager = { Server: function () { var config = (function () { var URL_Add = "/Finance/BillAjax/AddRec"; var URL_GetList = "/Finance/BillManagerAjax/GetList"; var URL_GetDetail = "/Finance/BillManagerAjax/GetDetail"; var URL_Delete = "/Finance/BillManagerAjax/Delete"; var URL_Cancel = "/Finance/BillManagerAjax/Cancel"; var URL_Audite = "/Finance/BillManagerAjax/Audite"; var URL_ToExcel = "/Finance/BillManagerAjax/ToExcel"; var URL_AddPay = "/Finance/BillAjax/AddPay"; var URL_PayDetail = "/Finance/BillAjax/AddRec"; return { URL_GetList: URL_GetList, URL_Add: URL_Add, URL_Delete: URL_Delete, URL_Cancel: URL_Cancel, URL_Audite: URL_Audite, URL_ToExcel: URL_ToExcel, URL_AddPay: URL_AddPay, URL_PayDetail: URL_PayDetail, }; })(); //数据操做服务 var dataServer = (function ($, config) { //查询分页列表 var Add=function(data,callback){ $.gitAjax({ url: config.URL_Add, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var GetList=function(data,callback){ $.gitAjax({ url: config.URL_GetList, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var Delete=function(data,callback){ $.gitAjax({ url: config.URL_Delete, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var Cancel=function(data,callback){ $.gitAjax({ url: config.URL_Cancel, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var Audite=function(data,callback){ $.gitAjax({ url: config.URL_Audite, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var ToExcel=function(data,callback){ $.gitAjax({ url: config.URL_ToExcel, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } var AddPay=function(data,callback){ $.gitAjax({ url: config.URL_AddPay, data: data, type: "post", dataType: "json", success: function (result) { if(callback!=undefined && typeof callback=="function"){ callback(result); } } }); } return { Add: Add, GetList: GetList, Delete: Delete, Cancel: Cancel, Audite: Audite, ToExcel: ToExcel, AddPay: AddPay, } })($, config); return dataServer; }, PageClick:function(PageIndex,PageSize){ $.jBox.tip("正在努力加载数据...","loading"); var Server=FinanceBillManager.Server(); var search=FinanceBillManager.GetSearch(); search["PageIndex"]=PageIndex; search["PageSize"]=PageSize; Server.GetList(search,function(result){ FinanceBillManager.SetTable(result); $.jBox.closeTip(); }); }, Refresh:function(){ var PageSize=$("#mypager").pager("GetPageSize"); var PageIndex=$("#mypager").pager("GetCurrent"); $.jBox.tip("正在努力加载数据...","loading"); var Server=FinanceBillManager.Server(); var search=FinanceBillManager.GetSearch(); search["PageIndex"]=PageIndex; search["PageSize"]=PageSize; Server.GetList(search,function(result){ FinanceBillManager.SetTable(result); $.jBox.closeTip(); }); }, SetTable:function(result){ $("#tabList").DataTable({ destroy: true, data:result.Result, paging:false, searching:false, scrollX: false, bAutoWidth:false, bInfo:false, ordering:false, columns: [ { data: 'SnNum' ,render:function(data, type, full, meta){ return "<input type='checkbox' name='bill_item' value='"+data+"' data-full='"+JSON.stringify(full)+"'/>"; }}, { data: 'BillNum'}, { data: 'Title'}, { data: 'CateName'}, { data: 'FromName'}, { data: 'Amount',render:function(data,type,full,meta){ return git.ToDecimal(data,2); }}, { data: 'RealPayAmount',render:function(data,type,full,meta){ return git.ToDecimal(data,2); }}, { data: 'LeavAmount',render:function(data,type,full,meta){ if(parseFloat(data)>0){ return '<span class="label label-warning">'+git.ToDecimal(data,2)+'</span>'; } else{ return "0.00"; } }}, { data: 'Status',render:function(data,type,full,meta){ if(data==EFinanceStatusJson.Pass){ return '<span class="label label-success">'+git.GetEnumDesc(EFinanceStatus,data)+'</span>'; }else if(data==EFinanceStatusJson.NotPass){ return '<span class="label label-warning">'+git.GetEnumDesc(EFinanceStatus,data)+'</span>'; }else{ return git.GetEnumDesc(EFinanceStatus,data); } }}, { data: 'CreateTime',render:function(data,type,full,meta){ return git.JsonToDateTime(data); }}, { data:"ID",render:function(data,type,full,meta){ var html=""; if(full.Status==EFinanceStatusJson.Wait || full.Status==EFinanceStatusJson.NotPass){ html+='<a class="edit" href="javascript:void(0)">编辑</a> '; } if(full.Status==EFinanceStatusJson.Wait || full.Status==EFinanceStatusJson.NotPass){ html+='<a class="audite" href="javascript:void(0)">审核</a> '; } html+='<a class="view" href="javascript:void(0)">查看</a> '; if(full.Status==EFinanceStatusJson.Wait || full.Status==EFinanceStatusJson.NotPass){ html+='<a class="delete" href="javascript:void(0)">删除</a> '; } if(full.Status==EFinanceStatusJson.Pass || full.Status==EFinanceStatusJson.PayPart){ html+='<a class="pay" href="javascript:void(0)">收款</a> '; } return html; }} ], aoColumnDefs:[ { "sWidth": "15px", "aTargets": [0] } ], oLanguage:{ sEmptyTable:"没有查询到任何数据" } }); var pageInfo=result.PageInfo; if(pageInfo!=undefined){ $("#mypager").pager({ pagenumber: pageInfo.PageIndex, recordCount: pageInfo.RowCount, pageSize: pageInfo.PageSize, buttonClickCallback: FinanceBillManager.PageClick }); } //绑定编辑 删除事件 FinanceBillManager.BindEvent(); }, BindEvent:function(){ $("#tabList").find("tbody td").popover({ container:"body", }); $("#tabList").find("a.edit").click(function(){ var SN=$(this).parent().parent().find("input[name='bill_item']").val(); FinanceBillManager.Detail(SN,"Edit"); }); //审核 $("#tabList").find("a.audite").click(function(){ var SN=$(this).parent().parent().find("input[name='bill_item']").val(); FinanceBillManager.Detail(SN,"Audite"); }); //查看 $("#tabList").find("a.view").click(function(){ var SN=$(this).parent().parent().find("input[name='bill_item']").val(); FinanceBillManager.Detail(SN,"View"); }); $("#tabList").find("a.delete").click(function(){ var SN=$(this).parent().parent().find("input[name='bill_item']").val(); var submit=function(v,h,f){ if(v=="ok"){ var list=[]; list.push(SN); var param={}; param["list"]=JSON.stringify(list); var Server=FinanceBillManager.Server(); Server.Delete(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); } } $.jBox.confirm("肯定要删除吗?", "提示", submit); }); //付款 $("#tabList").find("a.pay").click(function(){ var SN=$(this).parent().parent().find("input[name='bill_item']").val(); FinanceBillManager.Pay("",SN,"Add"); }); }, SelectAll:function(item){ var flag=$(item).attr("checked"); if(flag){ $("#tabList").find("input[name='bill_item']").attr("checked",true); }else{ $("#tabList").find("input[name='bill_item']").attr("checked",false); } }, GetSelect:function(){ var list=[]; $("#tabList").find("input[name='bill_item']").each(function(i,item){ var flag=$(item).attr("checked"); if(flag){ var value=$(item).val(); list.push(value); } }); return list; }, GetSearch:function(){ var searchBar=$("div[data-condition='search']"); var BillNum=searchBar.find("input[name='BillNum']").val(); var CateNum=searchBar.find("select[name='CateNum']").val(); var FromName=searchBar.find("input[name='FromName']").val(); var Title=searchBar.find("input[name='Title']").val(); var ContractNum=searchBar.find("input[name='ContractNum']").val(); var Status=$("div[data-group='Status']").find("button.disabled").attr("value"); var BeginTime=searchBar.find("input[name='BeginTime']").val(); var EndTime=searchBar.find("input[name='EndTime']").val(); var search={}; search["BillNum"]=BillNum; search["CateNum"]=CateNum; search["FromName"]=FromName; search["Title"]=Title; search["ContractNum"]=ContractNum; search["Status"]=Status; search["BeginTime"]=BeginTime; search["EndTime"]=EndTime; return search; }, Detail:function(SnNum,Command){ var currentSnNum=SnNum; var submit=function(v,h,f){ if(v=="1"){ var BillNum=h.find('input[name="BillNum"]').val(); var SnNum=h.find('input[name="SnNum"]').val(); var CateNum=h.find('select[name="CateNum"]').val(); var FromName=h.find('input[name="FromName"]').val(); var ToName=h.find('input[name="ToName"]').val(); var Amount=h.find('input[name="Amount"]').val(); var PrePayCount=h.find('input[name="PrePayCount"]').val(); var Remark=h.find('input[name="Remark"]').val(); var Title=h.find('input[name="Title"]').val(); var Remark=h.find('input[name="Remark"]').val(); var LastTime=h.find('input[name="LastTime"]').val(); var Title=h.find('input[name="Title"]').val(); var param={}; param["BillNum"]=BillNum; param["SnNum"]=SnNum; param["CateNum"]=CateNum; param["FromName"]=FromName; param["ToName"]=ToName; param["Amount"]=Amount; param["PrePayCount"]=PrePayCount; param["Status"]=1; //审核经过 param["Remark"]=Remark; param["LastTime"]=LastTime; param["Title"]=Title; var Server=FinanceBillManager.Server(); Server.Add(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); }else if(v=="2"){ }else if(v=="3"){ var param={}; param["SnNum"]=currentSnNum; param["Status"]=2; //审核经过 var Server=FinanceBillManager.Server(); Server.Audite(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); }else if(v=="4"){ var param={}; param["SnNum"]=currentSnNum; param["Status"]=3; //审核经过 var Server=FinanceBillManager.Server(); Server.Audite(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); } } // 1肯定 2 关闭 3 审核经过 4 审核不经过 if(Command=="View"){ $.jBox.open("get:/Finance/Bill/AddRec?SnNum="+SnNum, "查看应收", 670, 350, { buttons: {"关闭":2 } ,submit:submit,loaded:function(h){ h.find('input,select').attr('disabled',true); }}); }else if(Command=="Audite"){ $.jBox.open("get:/Finance/Bill/AddRec?SnNum="+SnNum, "审核应收", 670, 350, { buttons: {"审核经过": 3, "审核不经过": 4,"关闭":2 } ,submit:submit,loaded:function(h){ h.find('input,select').attr('disabled',true); }}); }else if(Command=="Add"){ $.jBox.open("get:/Finance/Bill/AddRec", "新增应收", 670, 350, { buttons: {"肯定": 1, "关闭":2 } ,submit:submit,loaded:function(h){ }}); }else if(Command=="Edit"){ $.jBox.open("get:/Finance/Bill/AddRec?SnNum="+SnNum, "编辑应收", 670, 350, { buttons: {"肯定": 1, "关闭":2 } ,submit:submit,loaded:function(h){ }}); } }, Pay:function(SnNum,BillSnNum,Command){ var currentSnNum=SnNum; var submit=function(v,h,f){ if(v=="1"){ var PayNum=h.find('input[name="PayNum"]').val(); var SnNum=h.find('input[name="SnNum"]').val(); var PayType=h.find('select[name="PayType"]').val(); var BankName=h.find('input[name="BankName"]').val(); var Amount=h.find('input[name="Amount"]').val(); var PayTime=h.find('input[name="PayTime"]').val(); var Remark=h.find('input[name="Remark"]').val(); var BillSnNum=h.find('input[name="BillSnNum"]').val(); var param={}; param["PayNum"]=PayNum; param["SnNum"]=SnNum; param["PayType"]=PayType; param["BankName"]=BankName; param["Amount"]=Amount; param["PayTime"]=PayTime; param["Remark"]=Remark; param["BillSnNum"]=BillSnNum; var Server=FinanceBillManager.Server(); Server.AddPay(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); }else if(v=="2"){ } } // 1肯定 2 关闭 if(Command=="Add"){ $.jBox.open("get:/Finance/Bill/AddPay?BillSnNum="+BillSnNum, "新增实收", 670, 300, { buttons: {"肯定": 1, "关闭":2 } ,submit:submit,loaded:function(h){ }}); }else if(Command=="Edit"){ $.jBox.open("get:/Finance/Bill/AddPay?BillSnNum="+BillSnNum+"&SnNum="+SnNum, "编辑实收", 670, 300, { buttons: {"肯定": 1, "关闭":2 } ,submit:submit,loaded:function(h){ }}); } }, ToolBar:function(){ //工具栏按钮点击事件 $("div.toolbar").find("a.btn").click(function(){ var command=$(this).attr("data-command"); if(command=="Add"){ FinanceBillManager.Detail(undefined,"Add"); }else if(command=="Edit"){ var list=FinanceBillManager.GetSelect(); if(list.length==0){ $.jBox.tip("请选择要编辑的项","warn"); return false; } var SN=list[0]; FinanceBillManager.Detail(SN,"Edit"); }else if(command=="Delete"){ var submit=function(v,h,f){ if(v=="ok"){ var list=FinanceBillManager.GetSelect(); if(list.length==0){ $.jBox.tip("请选择要删除的项","warn"); return false; } var param={}; param["list"]=JSON.stringify(list); var Server=FinanceBillManager.Server(); Server.Delete(param,function(result){ $.jBox.tip(result.Message,"success"); var pageSize=$("#mypager").pager("GetPageSize"); FinanceBillManager.PageClick(1,pageSize); }); } } $.jBox.confirm("肯定要删除吗?", "提示", submit); }else if(command=="Excel"){ var Server=FinanceBillManager.Server(); var search=FinanceBillManager.GetSearch(); Server.ToExcel(search,function(result){ if(result.Code==1000){ var path = unescape(result.Message); window.location.href = path; }else{ $.jBox.info(result.Message, "提示"); } }); }else if(command=="Refresh"){ FinanceBillManager.Refresh(); } }); //搜索 高级搜索按钮 var searchBar=$("div[data-condition='search']"); searchBar.find("a[data-command='search']").click(function(){ FinanceBillManager.PageClick(1,10); }); searchBar.find("button[data-command='Advanced']").click(function(){ var display=$("div.formsearch").css("display"); if(display=="block"){ $("div.formsearch").hide(300); }else{ $("div.formsearch").show(300); } }); searchBar.find("button[data-command='Clear']").click(function(){ //清空搜索条件 searchBar.find("input[name='BillNum']").val(""); searchBar.find("select[name='CateNum']").val(""); searchBar.find("input[name='FromName']").val(""); searchBar.find("input[name='Title']").val(""); searchBar.find("input[name='ContractNum']").val(""); searchBar.find("input[name='BeginTime']").val(""); searchBar.find("input[name='EndTime']").val(""); }); //状态按钮处理 $("div[data-group='Status']").find("button").click(function(){ $("div[data-group='Status']").find("button").removeClass("disabled"); $(this).addClass("disabled"); FinanceBillManager.PageClick(1,10); }); //加载默认数据 FinanceBillManager.PageClick(1,10); } }
在吉特仓储管理系统中,通过屡次的改版以后,最终肯定了JS的代码风格:
(1) 不必定要遵循世间的套路什么驼峰命名,帕斯卡命名,定好符合本身的规则
(2) 先后端数据传输Key名称尽可能和Model或者数据库字段一致,虽然违反了必定传统的命名规则
(3) 每一个模块定义一个对象,全部的操做方法都封装到对象中
(4) 尽可能作到UI分离,多使用事件驱动
ITopClient client = new TopClientDefault(); string list = WebUtil.GetFormValue<string>("list"); string CompanyID = this.CompanyID; Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("CompanyID", CompanyID); dic.Add("List", list); string result = client.Execute(DepartApiName.DepartApiName_Delete, dic); return Content(result);
调用API使用而代码示例
(1) 全部的代码都遵循如上操做方式,不得标新立异再作一套
(2) 请求API所有是使用POST的方式 (根据本身的状况来,有些人说这种作法很差,我以为挺好)
(3) 统一的数据返回格式JSON,也便于作拦截处理,代码要结构化
代码套路多,这里很少说 有兴趣去GitHub上下载开源版本的代码下来观摩
三. 八九月我激动过分
从未如此为项目激动,想着有一天软件可以被客户所可以接受,八九月的确有点出乎个人意料以外,吉特仓储管理系统已经不温不火的作了四年了,改版也不知道多少,虽然也有些客户在使用,但那终究不是我满意的结果,不是对客户不满意而是我在这些客户身上没有获取真正的价值,由于不少项目都是靠时间堆积起来的。八月九月两个月客户咨询的客户有点多,最终选择了几个客户合做, 项目金额超10W。 对于我如今一个兼职开发者(为生活所迫)来讲的确是一件可喜可贺的事情,不要拿这个跟某某公司来对比,我也历来不想超过哪一个公司,我只想认真的作好一个本身想作的软件。
10W+ 这远超过我工资收入,固然忙我也找了一些小伙伴帮忙,可是如今的确要比以前的处理速度要快不少。
8月初有个山西的客户联系我了,让我帮其弄一个仓库系统,说是给他们县城的小型加工厂使用,也就是云仓储。其实正中我下怀, 费用也就2W 我没有多要价,也想着拿新版本仓储系统试水, 20来天项目上线使用,客户爽快付款90%,听他说以前有个团队给他们弄了几个月还不是他想要的。
1. 项目大底开发速度高了不少
这几个客户开发效率本身明显推动速度高了不少,除了前期本身积累了大量的公共组建,现有成熟的软件以外,也积累了大量的客户犯错案例
2. 正确的引导客户
大多数客户其实不清楚本身要作什么东西的,若是对方是程序员我估计你会很沟通。首先给客户一个演示版本,让客户看是否是他想要的,若是不是那就不用谈了,避免浪费双方的时间
3. 合理的建议
在某种状况下你要决定的相信你的专业能力要比客户强,给客户实际的可见的演示软件,还要给客户说具体的案例,特别是案例中会出现的问题以及解决方式,合理的处理建议会让客户相信你的专业度
4. 多为客户考虑
多为客户考虑,有时候客户考虑的功能不多,你要合理的给客户新增一些业务功能,同时也要删减一些没必要要的需求,你的目的就是为他解决这个问题
5. 不要一味的谈技术
可能客户会处于礼貌的听你说你的技术如何的牛逼,可是客户绝大时候是听不懂在说什么的。 我会问客户的仓库规划状况,销售状况,打印状况,做业包装状况等,侧面找方式阐述你的解决方案
四. 软件版权保护
1. 软件著做权登记证书
不得不说有些人真的很可恶,吉特仓储管理系统(GitWMS)以前有一个版本开源以后,本身下载闷声去作客户就不说什么了,可是有些人却公开出售源码,以前还和某平台闹过一次。 这里很少说了,其实当时已经在申请软件著做权登记,这个登记证书终于下来了。
虽然不少人说这个东西没卵用,有时候这个东西是必须的,最起码在给别人说这个东西是我本身的时候有底气一点,看代码别人不认可是你的东西啊。
2. 如何看待开源问题
我从心里里面认可开源给我带来了不少的让我意向不到的好处,可是绝大部分来下载此代码的人都是程序员或者软件公司,他们问我出售价格以及使用技术,其实我更想听到合做意向,可是这种声音少之又少,同时还有更多的人或者企业拿到以后默默的去修改代码,去掉版权信息而后去作本身的客户,作本身的私单,而后有问题了就来像我咨询。其实我心里是高兴和纠结的,还有人说我是花了10块钱买的代码,留的联系方式是你的说能够提供技术支持,10块钱一顿饭都不够,并且钱不在我口袋。
(1). 开源的目的
我真正开源的目的是想让更多人了解个人项目,供你们一个能够参考学习的案例,最初我也没有想过有人能够拿着去卖钱或者直接修改给客户去使用,就算申明不能够给客户使用有些人仍是会默默的修改不露声色的去给客户使用,就比如说不能兜售源码可是仍是有人默默的在兜售源码。
(2). 你为何不所有开源
我开源了全部的业务代码,固然我也能够负所有责任的告诉你,新版本的是没有开源的(不要问我为何),以及底层的一些操做基本没有公开源代码,我相信代码已经流露在外面了。 公开的代码是2.0版本的代码,其中删除了一些非仓库业务的功能,其他功能模块代码彻底公开了,保证是一个能够正常运行,流程能够走通的,数据库结构所有公开的程序,没有任何的保留。
老是有人问我质问我,你这些都开源了为何还有底层的一些东西不开源,你就得将全部的代码所有开源,要否则你开源干吗。对于这种质问我很无奈, 打个不恰当的比喻,.NET如今也要开源了,为何他不开源他依托的Windows系统, 我想我也是这么想的。但愿你们可以读懂个人意思,有时候想作一个好事反而遭来辱骂声其实内心很不爽。
3. 开源带来更多的分享者以及潜在客户
其实我并非那么在意有人拿着我东西去作其余的客户,只但愿他们可以保留个人版权标题等基本信息,可是不少人作不到。自从开源以后个人确有不少开发者对此表示了兴趣,仔细个人人也不少,其实认真去看的人很少。每一个人内心都有这一个心理,开源的东西就是好东西,可是有多少人真正去看过开源的代码,更有甚者那些优秀的开源项目你下载以后看成安心石的代码你可以真的看得懂么。"若是开源你看不懂,那和不开源有什么区别" ,开源只是为那些懂的人而开源的。 固然也有不少人下载代码以后给我提了好多的意见,这些意见都是很是宝贵的,我在此很是的感谢这些人,分享各位的想法和经验,我才能作得更好。
五. 学习的参考对象
在博客园也算混了好久了,其中牛人比较多。至于哪些人是牛人我很少说,在开发吉特仓储管理系统的时候,我也参考过他们的模式。
吉日嘎拉: http://www.cnblogs.com/jirigala/ 当年他所开发的 通用权限管理系统
魏琼东: http://www.cnblogs.com/eastjade/ AgileEAS.NET SOA 中间件平台,医疗系统开发
路过秋天: http://www.cnblogs.com/cyq1162/ QBlog 博客
李天平: http://www.cnblogs.com/ltp/category/44293.html 代码生成器
麦舒: http://www.cnblogs.com/ansiboy/category/322450.html ALinq 当年也算雄霸一方
固然还有更多的优秀做品, 我参考过他们的不少运营模式。其中吉日嘎啦和魏琼东的相对是偏重业务行业性的, 最起码给个人感受是这样的,我没有深刻的去了解过他们的代码。其实我我的的侧重点也是如此,我更想但愿侧重于偏重行业性质的软件开发。
以前收入一直很低,其实老婆给我了很大的支持,我也很是惧怕她说我为何不找个正经的工做去干,每天折腾这些东西。我给她玩笑的说,我说我用吉特仓储管理系统能够赚到100W, 而后我也就笑笑,她也就笑笑。我说知道大家不会相信个人,我说赚不到100W我赚50W也能够,再不行30W也能够。
我一直坚信本身可以作到,固然过去的几年我也曾一度怀疑本身,虽然如今这个也很遥远,可是我但愿本身依旧坚持。
参考了不少产品,大致上能够分为两种: (1) 以技术型为主,也就是技术开发框架或者组件, 麦舒的就是典型的案例 (2) 以业务型为主,老魏的医疗系统绝对的偏向行业性质
且不论这二者之间各有什么优缺点,但坚信一点只要你坚持去作持续改进都可以作出好东西来。
此文有点啰嗦,有不正之处望请谅解,有心在业余时间发展我的仓储系统,若是对此感兴趣的朋友能够下载开源版本的代码研究并和本人交流,但愿可以给到更多更好的建议。
做者:情缘
出处:http://www.cnblogs.com/qingyuan/
关于做者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路
版权声明:本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接。
联系方式: 我的QQ 821865130 ; 仓储技术QQ群 88718955,142050808 ;
吉特仓储管理系统 开源地址: https://github.com/hechenqingyuan/gitwms