胡建飛,焦振峰,張 祥,丁 靖
(1. 中海油能源發(fā)展股份有限公司管道工程分公司,天津 300452;2. 海油發(fā)展珠海管道工程有限公司,珠海 519000)
管道涂敷是海底管道建設的一個重要組成部分,海油發(fā)展珠海管道工程有限公司是一家主要從事海底管道涂敷的企業(yè)。在涂敷過程中需要記錄大量生產檢驗數據,在沒有計算機技術支持的時代使用紙張記錄,造成報表數量繁多,數據無法查詢等缺點。
隨著計算機技術的引用,數據無法查詢慢慢得到改善,初期我們使用單機數據庫來記錄生產檢驗數據,但新的問題隨之而來:需要配備專門的數據錄入人員,查詢也只能通過一臺電腦。
隨著ASP.NET技術的長足發(fā)展,B/S模式的網站式軟件越來越受到開發(fā)者的關注,使用ASP.NET開發(fā)新一代的數據跟蹤軟件成為海油發(fā)展珠海管道工程有限公司2017年的科研項目之一。
海洋中的油氣田通過管道把油氣輸送到陸地上,管道由鋼管建造,鋼管要在海水中能夠長期使用,必須要在鋼管表面涂一層防腐層,現在常用的工藝叫做三層結構聚乙烯防腐涂層,簡寫做3LPE。另外一種防腐的工藝是安裝犧牲陽極,即在鋼管通過導線連接一定重量的鋁塊,鋼管和鋁塊構成原電池,通過不斷腐蝕陽極鋁塊的方式來保護鋼管。
鋼管是中空的,整體比重和海水相差不大,為了能讓鋼管穩(wěn)定的沉在海底,需要在鋼管外部加一層混凝土涂層,增大鋼管的整體比重。
鋼管涂敷的第一步工序是接收鋼管,鋼管檢驗合格后可進行3LPE、安裝陽極、配重等各道涂敷工序,涂敷完成后進行發(fā)運,所有的步驟都要記錄相關數據。
如果所有步驟都使用紙張記錄數據的話,這些分布的數據要最后通過一個專門的數據錄入人員錄入電腦,需要設置專門的數據錄入人員,且抄寫紙質記錄時發(fā)生的錯誤無法及時發(fā)現,要解決這些問題最佳的方式就是開發(fā)B/S模式數據庫軟件。
開發(fā)B/S模式軟件有很多工具可以供選擇,當前企業(yè)開發(fā)小型的 B/S模式軟件以 ASP.NET為首選。原因如下:[1,3,4,5]
第一,ASP.NET可以使用多種語言,如 C#、VB script等,都是最常見的編程語言,掌握的人非常多。
第二,ASP.NET學習入門門檻低,上手快,企業(yè)內部交接工作時可選擇的人力資源比較廣。
本次軟件開發(fā)服務器采用了 windows server 2008,開發(fā)工具使用 ASP.NET,開發(fā)語言使用 C#語言,后臺服務器使用SQL server2008。
考慮到車間質檢員位置不固定,經常要走來走去,所以輸入設備采用無線手持設備,網絡設計主要采用了無線網絡。[2]
網絡結構如圖1所示。
服務器安裝在辦公樓機房,通過光纜連接到車間的弱電機房,由車間的弱電機房連接分布在車間內外的數個無線接入點AP。
服務器配置兩塊網卡,一塊網卡連接公司局域網,另外一塊網卡連接中海油的VPN網絡,這樣可以在任意地點通過 VPN網絡訪問服務器查詢生產數據。
圖1 網絡布線圖Fig.1 Network cabling diagram
因為本系統(tǒng)要多人協同錄入數據,數據的安全性非常重要,一定要對各個操作者設置不同的權限,首先要做的就是通過登錄確定操作者的身份。
密碼對于每個人都是隱私的數據,所以一定要加密存儲,一為安全,二為操作者可以放心設置自己常用的密碼,不用擔心泄露的問題。
密碼加密算法通常是用.NET內置的MD5加密算法,雖然MD5加密算法一般無法破譯,但我們還是對MD5生成的密碼進行簡單的改造,成為我們獨有的加密算法,使其被破解變得不可能。
加密函數如下:
public string GetMD5(string strPwd)
{
string pwd = "";
MD5 md5 = MD5.Create();//實例化一個md5對象
byte[] s = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(strPwd)); // 加密后是一個字節(jié)類型的數組
s.Reverse();//翻轉生成的MD5碼
for (int i = 3; i < s.Length - 1; i++)//通過使用循環(huán),將字節(jié)類型的數組轉換為字符串,只取MD5碼的一部分,這樣惡意訪問者無法知道取的是哪幾位
{
pwd = pwd + (s[i] < 198 ? s[i] + 28 :s[i]).ToString("X");
//將得到的字符串使用十六進制類型格式。格式后的字符是小寫的字母,如果使用大寫(X)則格式后的字符是大寫字符
}
return pwd;
}
通過以上算法,用戶設置的密碼被轉化為一串大寫字母存放在數據庫中,除了設置者本人,任何人無法得知用戶設置的密碼。
用戶登錄時,用戶輸入的密碼通過相同的算法生成一串大寫字母,和數據庫存儲的進行比對,如果相同,則認為輸入了正確的密碼,服務器建立一個以用戶名稱為ID的session對象,用戶對數據庫進行操作時,服務器通過這個session對象辨別用戶身份。
企業(yè)的服務器雖然不會有黑客來攻擊,但企業(yè)內別有用心之人卻不得不防,如果登錄僅僅輸入一個用戶名和密碼,那在網絡上下載一個暴力密碼破解器就可以破解密碼,而且會對服務器造成比較大的負擔,為解決這一問題,同大多網站一樣,本系統(tǒng)使用了驗證碼技術。
首先用函數生成一個四位的隨機數,轉化為字符串validateNum,通過下面的函數轉化為略不清晰圖片,在登錄框的驗證碼輸入框后顯示這個圖片,因隨機數函數每次生成的字符串都不一樣,可以保證每次驗證碼都是隨機的,驗證碼圖片生成函數如下:
private void CreateImage(string validateNum)
{
if (validateNum == null || validateNum.Trim() ==
String.Empty) return;
System.Drawing.Bitmap image = new System.Drawing.
Bitmap(validateNum.Length * 12 + 10, 22); //生成Bitmap圖像
Graphics g = Graphics.FromImage(image);
{
Random random = new Random();
g.Clear(Color.White); //清空圖片背景色
for (int i = 0; i < 25; i++)//畫圖片的背景噪音線
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1,x2, y2);
}
Font font = new System.Drawing.Font("Arial", 12,(System.Drawing.FontStyle.Bold |
System.Drawing.FontStyle.Italic));
System.Drawing.Drawing2D.LinearGradientBrush
brush = new System.Drawing.Drawing2D.LinearGrad
ientBrush(new Rectangle(0, 0, image.Width, image.
Height), Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateNum, font, brush, 2, 2);
//畫圖片的前景噪音點
for (int i = 0; i < 100; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y,
Color.FromArgb(random.Next()));
}
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.
Width - 1, image.Height - 1); //畫圖片的邊框線
System.IO.MemoryStream ms = new
System.IO.MemoryStream();
image.Save(ms,
System.Drawing.Imaging.ImageFormat.Gif); //將圖像保存到指定的流
Response.ClearContent();
Response.ContentType = "image/Gif";Response.BinaryWrite(ms.ToArray());
}
用戶提交賬戶密碼時,必須先正確輸入這個驗證碼,系統(tǒng)才會去驗證賬戶密碼。
鋼管的存儲是以鋼管垛的方式進行的,如圖 2所示。
圖2 鋼管垛Fig.2 Steel pipe stacking
每垛鋼管數量不固定,少則幾十根,多則幾百根,如果用軟件直觀的顯示出來,控件數組是最好的選擇,下面我們使用 Textbox控件數組按鋼管堆垛的樣式去顯示,代碼如下[6,9]:
pp.Attributes.Add("style","white-space:nowrap");
pp.Controls.Clear();
//頁面中建立一個名為 pp的 panel控件,下面所建立的所有控件數組都加入到這個 pp中,用 pp指定我們的垛位圖要顯示在網頁中的位置
ppp = new Panel[Convert.ToInt16(ViewState["y"])];
//根據垛位圖的行數y建立panel數組,每行用一個panel
TT = new TextBox[Convert.ToInt16(ViewState["x"]),Convert.ToInt16(ViewState["y"])];
//根據垛位圖的行數y和列數x建立textbox二維數組if (ViewState["x"] != null) //從頁面別的函數傳遞過來的垛位列x值
{
for (int i = Convert.ToInt16(ViewState["y"]) - 1; i>= 0; i--)
{//每循壞一次,寫一行
ppp[i] = new Panel();
pp.Controls.Add(ppp[i]); //加入當前行的panel控件
if (i % 2 == 0)
{
TextBox tempt = new TextBox();
tempt.Width = 50;
tempt.Height = 20;
tempt.BorderWidth = 0;
ppp[i].Controls.Add(tempt);
tempt.Enabled = false;
// 偶數行建立一個長度為 50且不可使用的textbox控件用來調整本行控件位置,以達到鋼管兩層之間互相交叉的效果
}
for (int j = 0; j < Convert.ToInt16(ViewState["x"]); j++)
{
TT[j, i] = new TextBox();
ppp[i].Controls.Add(BB[j, i]);
ppp[i].Controls.Add(TT[j, i]);
TT[j, i].BorderWidth = 1;
TT[j, i].Width = 98;
TT[j, i].Height = 18;
//將這一行所有的textbox控件加入到這一行的pannel控件ppp。
TT[j, i].TextChanged += new EventHandler(TextBox1_TextChanged);
//為每一個textbox控件添加相應方法
TT[j, i].Text = "";
TT[j, i].ID = "T_" + j.ToString() + "_" +i.ToString();}}}
//初始化textbox控件顯示的內容和ID
圖3是代碼運行并寫入管號后的樣式,數據庫記錄下每個管號的行y和列x值,在需要的時候可以將鋼管垛位圖顯示在網頁上,通過數據庫查詢可以精確知道任意一個鋼管的位置。建立新的垛位時,我們可以通過調整行數y和列數x調整鋼管垛的大小。
需要注意的是,控件數組在網頁每次刷新時都需要重新加載一次,就是說我們上面顯示控件數組的代碼每次頁面加載都要運行一次,這和我們大多數人的認識不同,重新加載這些控件數組,控件顯示的內容并不會丟失,服務器使用viewstate對象記錄每個控件的信息。
圖3 鋼管垛Fig.3 Steel pipe stacking
海油發(fā)展珠海管道工程有限公司使用ASP.NET自主研發(fā)的數據跟蹤系統(tǒng)軟件將鋼管涂敷數據記錄實現了網絡化多人協同錄入,每個用戶可以設置不同的權限,保證了數據的安全性,同時取消了紙質報表的記錄,減輕了數據記錄的工作量。批量減少紙質報表的數量,為后期完工文件的整理節(jié)省大量人力物力。數據共享在服務器上,可通過網絡在服務器上查詢生產檢驗數據,信息流轉加快,初步實現了這一工作的信息化。
[1] 龐婭娟, 房大偉, 呂雙. ASP.NET從入門到精通, 清華大學出版社.
[2] JavaScript從入門到精通, 清華大學出版社.
[3] 蔣順業(yè). ASP.NET應用程序開發(fā)軟件設計與應用研究[J].軟件, 2017, 37(10): 95-97.
[4] 蘭洋, 蔣順業(yè). 基于asp.net的FMS生產管理系統(tǒng)[J]. 軟件,2013, 34(5): 76-78.
[5] 余翠蘭. 基于ASP.NET的學生住宿管理系統(tǒng)的設計與實現[J]. 軟件, 2014, 35(4): 37-41.
[6] 賈志先. 袁芳. 基于ASP.NET數據分頁導航的設計與應用[J]. 軟件, 2015, 36(12): 60-62.
[7] 周瑞. 從零開始學JavaScript, 電子工業(yè)出版社.
[8] VB.NET 2005程序設計從入門到精通, 人民郵電出版社.
[9] Java從入門到精通, 清華大學出版社.
[10] 袁芳. 教學做一體化ASP.NET課程教學改革與實踐[J]. 軟件, 2014, 35(11): 126-128.