基于EasyUI的Web應(yīng)用程序及過(guò)去一年的總結(jié)
過(guò)去一年的總結(jié)
在過(guò)去一年的時(shí)間里,跟著現(xiàn)在這家公司(簡(jiǎn)稱B公司)的領(lǐng)導(dǎo)和同事學(xué)到很多東西,我覺(jué)得在這一年中主要是從技術(shù)與溝通方面得到了提高:
1.技術(shù)方面
1.1之前一直做客戶端的開(kāi)發(fā),所以對(duì)那些腳本語(yǔ)言用的比較少,在這里加深了JQuery,JS的使用。
1.2對(duì)Ajax的異步使用多了一些了解。
1.3學(xué)會(huì)了如何使用SQL監(jiān)控,學(xué)會(huì)了一些優(yōu)化SQL語(yǔ)句的方法,當(dāng)然這都是在實(shí)際項(xiàng)目中積累的經(jīng)驗(yàn),比較寶貴。
1.4學(xué)會(huì)了使用客戶端與網(wǎng)頁(yè)端的互相調(diào)用、嵌套來(lái)開(kāi)發(fā)應(yīng)用系統(tǒng)。
1.5了解了跨域請(qǐng)求的處理方法。
2.溝通方面
2.1搞IT的其實(shí)是一個(gè)服務(wù)角色,所以與用戶溝通的時(shí)候要找到自己的定位。
2.2不管用戶的要求是否合理,溝通的時(shí)候都不要充滿火藥味兒。
2.3互相尊重很重要,尊重對(duì)方也會(huì)使對(duì)方尊重自己。
為什么離開(kāi)
來(lái)到B公司之前,在一家上市集團(tuán)公司(簡(jiǎn)稱A公司)做公司內(nèi)部的應(yīng)用系統(tǒng)開(kāi)發(fā),整整服務(wù)了3年,到目前為止,離開(kāi)A公司已經(jīng)一年十個(gè)月了,在這 期間跟之前的領(lǐng)導(dǎo)一直還是有聯(lián)系,當(dāng)然,這沒(méi)別的意思,主要是畢竟在那里工作了3年,也是我參加工作以來(lái)服務(wù)時(shí)間最長(zhǎng)的一家公司,多少還是有一些情誼存在 的,在我進(jìn)入到B公司之后,之前A公司的領(lǐng)導(dǎo)找到了我,目的是叫我利用業(yè)余時(shí)間幫忙開(kāi)發(fā)一套應(yīng)用系統(tǒng),我聽(tīng)了二話沒(méi)說(shuō)就答應(yīng)了,為什么這么爽快呢?有如下 幾個(gè)原因:
1.當(dāng)時(shí)我離開(kāi)的比較匆忙,可能交接的不是那么仔細(xì),這一點(diǎn)我一直覺(jué)得過(guò)意不去。
2.在我離開(kāi)A公司的前一天,也就是周四(因?yàn)轭I(lǐng)導(dǎo)是HK那邊的,每周四下午都會(huì)回去HK),領(lǐng)導(dǎo)去到我辦公的地方對(duì)我說(shuō):“xxx,那我走 了...”,后面的我就沒(méi)聽(tīng)清楚了,因?yàn)楫?dāng)時(shí)有 點(diǎn)受寵若驚的感覺(jué),他一個(gè)高級(jí)領(lǐng)導(dǎo),完全可以不用把我這個(gè)小嘍啰當(dāng)回事兒的,就算是打招呼也應(yīng) 該是我去給他打招呼才對(duì),這個(gè)事情讓我一直心存感激,我覺(jué)得在當(dāng)時(shí)來(lái)說(shuō)他 給我面子了。
3.在給我辦離職事宜上,很多細(xì)節(jié)方面領(lǐng)導(dǎo)都為我考慮到了,比如說(shuō)我離開(kāi)的突然,按照人事部要求的話時(shí)間達(dá)不到,提前離開(kāi)的話需要扣工資,但是他給我把簽批日期提前了,雖然是一些小事情,但是讓人心里暖暖的。
上面貌似扯了很多廢話,言歸正傳,我的原意是在我能力范圍內(nèi)免費(fèi)幫忙開(kāi)發(fā),因?yàn)槲冶旧硎歉氵@一行的,技術(shù)不是問(wèn)題,就是多花點(diǎn)時(shí)間而已,但是項(xiàng)目完 成之后領(lǐng)導(dǎo)還是給了我意想不到的報(bào)酬,在這里要感謝一下他們的照顧,當(dāng)然這個(gè)項(xiàng)目也是幾經(jīng)波折才完成,畢竟我是業(yè)余的,不在同一個(gè)地方,溝通很不方便(說(shuō) 實(shí)話,通過(guò)這一次我也學(xué)到了很多)。
在這期間,領(lǐng)導(dǎo)跟我談話幾次,目的是希望我能回去工作;因?yàn)橹坝泻芏囗?xiàng)目都是我跟進(jìn)的,領(lǐng)導(dǎo)可能是考慮到我比較熟悉一點(diǎn)吧,我考慮了很久,最終還是答應(yīng)了,所以才向B公司這邊提出離開(kāi)的要求;說(shuō)實(shí)話,在這之前我從沒(méi)想過(guò)我還會(huì)回去,真的沒(méi)想到,真的是世事難料...
回去之后的工作目標(biāo)
1.盡量統(tǒng)一開(kāi)發(fā)語(yǔ)言,之前的項(xiàng)目存在多種開(kāi)發(fā)語(yǔ)言,比如VB6,C++,VFP,ASP,Delphi,C#,至今還有DOS操作系統(tǒng)的程序,何 必呢?難道要我精通各種開(kāi)發(fā)語(yǔ)言嗎?或者說(shuō) 每一門開(kāi)發(fā)語(yǔ)言找一個(gè)對(duì)應(yīng)的開(kāi)發(fā)者嗎?該砍的砍、該升級(jí)的升級(jí),不然不管是誰(shuí)都玩 不下去。
2.后續(xù)的項(xiàng)目以Web結(jié)構(gòu)為主,便于更新;客戶端為輔,涉及到跟硬件通信的功能采用客戶端與Web結(jié)合來(lái)完成。
3.將眾多的小程序集成到一個(gè)框架中,不要搞的那么分散(目前存在很多的小程序、小補(bǔ)丁),不要再不停的“打補(bǔ)丁”。
4.搭建一個(gè)好的源代碼管理平臺(tái),不管是TFS還是SVN都可以。
最近一個(gè)Web應(yīng)用程序
我這個(gè)人就是這樣,看見(jiàn)別人好的東西就想學(xué)習(xí)過(guò)來(lái),剛來(lái)到B公司的時(shí)候,看見(jiàn)公司用的很多功能都比較高大上,我的學(xué)習(xí)方法是這樣的:先了解這些 高大上的功能是如何實(shí)現(xiàn)的,不懂就請(qǐng)教前輩,這里又得感謝一下我的師傅了,感謝他不吝賜教、悉心指導(dǎo);了解之后就自己創(chuàng)建一個(gè)項(xiàng)目試著搞一個(gè)Demo出 來(lái),在這個(gè)過(guò)程中遇到不懂的就再次請(qǐng)教別人,直到自己搞懂為止,那么到了這個(gè)時(shí)候這東西已經(jīng)“屬于”我自己的了,我已經(jīng)裝進(jìn)腦袋里面去了,所以從進(jìn)入B公 司開(kāi)始我就沒(méi)有停止過(guò)學(xué)習(xí)。不管學(xué)到什么知識(shí),一定要運(yùn)用起來(lái)才行,只有在實(shí)際項(xiàng)目中才能學(xué)到更多、才能找出自己的不足,所以下面的項(xiàng)目就是我剛進(jìn)入B公 司就開(kāi)始著手開(kāi)發(fā)的,借鑒了一些前輩們的東西,但不是直接COPY,只有圖片和CSS樣式是用的原來(lái)的,因?yàn)楸救嗣拦ぜ夹g(shù)實(shí)在太差,想PS出來(lái)一個(gè) LOGO圖片就搞了很多次,PS出來(lái)的結(jié)果連自己看著就不爽,所以就不強(qiáng)求了,引用了之前的一些圖片和樣式,這里值得說(shuō)明的是:現(xiàn)有公司的項(xiàng)目和數(shù)據(jù)庫(kù)結(jié)構(gòu)我們開(kāi)發(fā)人員都有,這也是領(lǐng)導(dǎo)批準(zhǔn)的,因?yàn)槲覀冇袝r(shí)候會(huì)在家里辦公,所以會(huì)將數(shù)據(jù)庫(kù)結(jié)構(gòu)和程序復(fù)制在本地以便創(chuàng)建真實(shí)的開(kāi)發(fā)環(huán)境和調(diào)試環(huán)境。
除了圖片以外其它的我都按照我自己的設(shè)計(jì)開(kāi) 發(fā)的,包括數(shù)據(jù)庫(kù)設(shè)計(jì)和項(xiàng)目架構(gòu)設(shè)計(jì),后續(xù)我會(huì)抽時(shí)間將這個(gè)項(xiàng)目繼續(xù)完善,主要是針對(duì)制造行業(yè),現(xiàn)在只有幾個(gè)基礎(chǔ)的功能,也可以說(shuō)是制造行業(yè)里面基本上都 會(huì)用到的幾個(gè)功能,比如條碼管控與打印之類的,根據(jù)實(shí)際的需求可以靈活擴(kuò)展,以下是部分截圖:
描述:
條碼規(guī)則就是用來(lái)控制條碼的格式,對(duì)于現(xiàn)在的工廠來(lái)說(shuō),條碼化管控是最常見(jiàn)的,那么不同的產(chǎn)品有不同的條碼格式要求,每一個(gè)客戶也都有自己的特殊要求,所以這個(gè)條碼規(guī)則也是非常重要的,在這之前我的做法如下:
在數(shù)據(jù)庫(kù)中根據(jù)當(dāng)前年月日+流水號(hào)來(lái)自動(dòng)生成,這樣本來(lái)也能解決問(wèn)題,但是如果需要擴(kuò)展的時(shí)候就歇菜了,只要客戶要求條碼格式稍微改變一下格 式,那么我們需要改變的東西是相當(dāng)?shù)亩?,甚至可能因此帶?lái)很多嚴(yán)重的問(wèn)題,因?yàn)楦袷揭呀?jīng)固定不能靈活變更,所以幾乎沒(méi)有擴(kuò)展的可能性。
#p#
鑒于此,現(xiàn)在的做法如下:
定義一個(gè)條碼規(guī)則,包含條碼的計(jì)算進(jìn)制、需要屏蔽的字母或字符、條碼前綴、條碼后綴、條碼總長(zhǎng)度、流水號(hào)長(zhǎng)度等等參數(shù),在生成條碼的時(shí)候選擇此 規(guī)則即可,如果有新的格式要求,那只需要針對(duì)新的格式要求新增一個(gè)條碼規(guī)則即可,對(duì)原有的數(shù)據(jù)結(jié)構(gòu)完全沒(méi)有影響,靈活多變、擴(kuò)展容易!
描述:
生成條碼屬于一個(gè)比較關(guān)鍵的功能,有時(shí)候數(shù)據(jù)量可能比較大,例如某一個(gè)工單的數(shù)量是20000,那也就是說(shuō)用戶生成條碼的時(shí)候一次性就要在數(shù)據(jù) 庫(kù)產(chǎn)生20000筆記錄,根據(jù)我個(gè)人的經(jīng)驗(yàn)來(lái)說(shuō),這種事物不能直接交由用戶來(lái)操作,防止數(shù)據(jù)庫(kù)被拖死;我的做法是不管用戶提交多少數(shù)量,在服務(wù)器中將用戶 提交的請(qǐng)求保存起來(lái),服務(wù)器定時(shí)去處理這些請(qǐng)求,每次按照時(shí)間排序處理最先提交的一筆請(qǐng)求,如果用戶的請(qǐng)求中出現(xiàn)不合法的數(shù)據(jù),則服務(wù)器直接將該請(qǐng)求駁回 并通知到用戶,反之則完成相關(guān)的操作,這樣一來(lái)可以避免用戶直接操作大量的數(shù)據(jù)而導(dǎo)致系統(tǒng)變得緩慢或者數(shù)據(jù)庫(kù)出現(xiàn)死鎖之類的問(wèn)題。
描述:
工藝路線方面這里值得說(shuō)一下,采用了gooflow設(shè)計(jì),當(dāng)然gooflow只有UI部分,后臺(tái)都是另外設(shè)計(jì)的。
支持多節(jié)點(diǎn)工藝路線,這里需要設(shè)置條件,例如:當(dāng)前我們前面有兩條路,路線A通向北京,路線B通向上海,我們現(xiàn)在站在路口選擇具體走哪一條路? 這個(gè)時(shí)候就需要條件了,我們現(xiàn)在的目的是去北京看故宮,那很顯然已經(jīng)匹配到了條件,說(shuō)明我們應(yīng)該走路線A;系統(tǒng)會(huì)根據(jù)具體的情況來(lái)尋找應(yīng)該走哪一條線,這 個(gè)邏輯比較復(fù)雜。
描述:
動(dòng)態(tài)報(bào)表,可以根據(jù)不同的條件動(dòng)態(tài)生成控件,實(shí)現(xiàn)查詢功能,這樣可以省掉很多的報(bào)表,簡(jiǎn)單的查詢功能用這個(gè)足以。
描述:
維修功能其實(shí)是一個(gè)比較復(fù)雜的業(yè)務(wù),根據(jù)不同的維修動(dòng)作而產(chǎn)生不同的數(shù)據(jù)結(jié)構(gòu),比如說(shuō)維修動(dòng)作中包含“簡(jiǎn)單維修”,“更換物料”,“報(bào)廢”等選 項(xiàng),像簡(jiǎn)單維修就比較容易處理,只需按照正常的工藝路線操作并記錄修理過(guò)程即可,但是更換物料就不一樣了,需要記錄更換了什么物料?原始料號(hào)是什么?更換 上去的料號(hào)是什么?包括Vendor,DateCode等信息;一般生產(chǎn)管理的應(yīng)用系統(tǒng)中,客戶都會(huì)要求有詳細(xì)的維修記錄和報(bào)表,這是一個(gè)重點(diǎn)。
描述:
以下都是調(diào)用Api實(shí)現(xiàn)的,具體的邏輯都在Api里面實(shí)現(xiàn),Api采用工廠模式設(shè)計(jì),根據(jù)不同的需求產(chǎn)生不同的數(shù)據(jù)結(jié)構(gòu),這些頁(yè)面沒(méi)有寫一句后臺(tái)代碼,全是腳本。
描述:
在開(kāi)發(fā)過(guò)程中,會(huì)涉及到很多的錯(cuò)誤信息,既有存儲(chǔ)過(guò)程中的也有程序里面的,之前我的做法是直接將報(bào)錯(cuò)的存儲(chǔ)過(guò)程名稱寫在錯(cuò)誤信息后面,這樣一看 就知道是哪一個(gè)存儲(chǔ)過(guò)程拋出的錯(cuò)誤,直接就可以進(jìn)行錯(cuò)誤定位,但是發(fā)現(xiàn)一個(gè)問(wèn)題,存儲(chǔ)過(guò)程的名稱字符串長(zhǎng)度無(wú)法統(tǒng)一,導(dǎo)致頁(yè)面布局不好控制;鑒于此,我統(tǒng) 一用ErrorCode來(lái)代替錯(cuò)誤信息,針對(duì)用戶來(lái)說(shuō),用戶并不需要知道是哪個(gè)地方報(bào)錯(cuò),系統(tǒng)管理員或者開(kāi)發(fā)人員根據(jù)ErrorCode對(duì)照表也能快速定 位問(wèn)題點(diǎn),如此可以解決由于錯(cuò)誤信息長(zhǎng)度不統(tǒng)一而導(dǎo)致的頁(yè)面布局問(wèn)題,ErrorCode對(duì)照表如下圖所示:
以上都是介紹了部分Web中的功能,整個(gè)項(xiàng)目還有一部分是客戶端,客戶端其實(shí)比較好理解,主要是在客戶端調(diào)用了Web程序,客戶端主窗體代碼如下,當(dāng)然只是部分代碼,根據(jù)實(shí)際情況可以另行增加。
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Security.Permissions;
- namespace MES
- {
- [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FrmMain : Form
- {
- public FrmMain()
- {
- InitializeComponent();
- }
- public WebBrowser Browser { get { return this.webBrowser1; } }
- private void FrmMain_Load(object sender, EventArgs e)
- {
- string ConfigPath = Application.StartupPath + "\\config.ini";
- if (!System.IO.File.Exists(ConfigPath))
- {
- MessageBox.Show("缺少配置文件,系統(tǒng)無(wú)法啟動(dòng),請(qǐng)聯(lián)系管理員!", "溫馨提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- Application.Exit();
- GC.Collect();
- return;
- }
- MES.Common.Global.ApiUrl = MES.Common.IniHelper.GetConfigValue("ApiUrl");
- MES.Common.Global.serverPath = MES.Common.IniHelper.GetConfigValue("ServerPath");
- webBrowser1.ObjectForScripting = this;
- webBrowser1.Navigate(MES.Common.Global.serverPath);
- }
- public void Print_ZPL(string Content)
- {
- System.Drawing.Printing.PrintDocument p = new System.Drawing.Printing.PrintDocument();
- string DefaultPrint = p.PrinterSettings.DefaultPageSettings.PrinterSettings.PrinterName;
- MES.Common.PrintHelper.PrintLabel(DefaultPrint, Content);
- }
- private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
- {
- webBrowser1.ScriptErrorsSuppressed = true; //禁用腳本調(diào)試,屏蔽腳本錯(cuò)誤提示框
- }
- /// <summary>
- /// 獲取稱重機(jī)的重量
- /// </summary>
- /// <param name="Com">通信COM口</param>
- /// <param name="CheckCount">循環(huán)次數(shù)</param>
- /// <returns></returns>
- public string GetWeigh(string Com,int CheckCount)
- {
- return MES.Common.WeighHelper.GetWeighData(Com, CheckCount);
- }
- /// <summary>
- /// 獲取本地計(jì)算機(jī)上面的COM列表
- /// </summary>
- /// <returns></returns>
- public string GetComList()
- {
- string str = "";
- List<string> list= MES.Common.WeighHelper.GetComList();
- for (int i = 0; i < list.Count; i++)
- {
- str += list[i].ToString() + ",";
- }
- return str;
- }
- }
- }
至于如何回調(diào)客戶端的函數(shù),可以參考這篇文章:理解JavaScript回調(diào)函數(shù)