<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ASP.NET 大學(xué)場地預(yù)約借用系統(tǒng)(源碼+數(shù)據(jù)庫)

          共 17540字,需瀏覽 36分鐘

           ·

          2021-06-12 21:11

          這個是我在修專業(yè)課《Web應(yīng)用開發(fā)技術(shù)》時(shí)的結(jié)課作業(yè),分組是按5人一組的。結(jié)果由于我是大四老學(xué)長回來補(bǔ)修的。就自己單干了。采用了asp.net技術(shù)開發(fā)的,前端用了一些CSS框架進(jìn)行美化。數(shù)據(jù)交互采用AJAX,數(shù)據(jù)庫用的SQL Sever。

          1、目標(biāo)與應(yīng)用場景

          同學(xué)們在進(jìn)行各類活動時(shí),通常需要一定的場地配合。如果是室外場地,例如操場等無需進(jìn)行借用預(yù)約便可使用。但是大部分活動都需要在室內(nèi)場地完成,例如開團(tuán)員大會,開班會,班級聯(lián)誼等。再者,教師群體需要舉辦學(xué)術(shù)交流活動等也需要室內(nèi)的場地完成。華中科技大學(xué)的教室和公用場地十分充足,即使在工作日,也有很多空閑的場地剩余。場地包括啟明學(xué)院、教學(xué)樓、學(xué)生公寓內(nèi)部的公用房、學(xué)院內(nèi)的教室等。為滿足廣大同學(xué)的學(xué)習(xí)活動需求,促進(jìn)同學(xué)之間的交流,同時(shí)更加充分地利用公共教室范圍內(nèi)的場地,我們小組決定設(shè)計(jì)并實(shí)現(xiàn)華中科技大學(xué)的場地預(yù)約系統(tǒng),該系統(tǒng)的需求如下:

          • 用戶可以登錄系統(tǒng),進(jìn)行教室的預(yù)約。
          • 系統(tǒng)需要支持多用戶使用,用戶之間同一教室的預(yù)約時(shí)間段不能沖突。
          • 如果不需要教室了,用戶可以選擇取消自己的預(yù)約。
          • 用戶能看到自己的歷史預(yù)約信息。

          根據(jù)以上的需求,擬實(shí)現(xiàn)的系統(tǒng)功能如下:

          • 登錄注冊:新用戶可以通過注冊頁面進(jìn)行注冊,隨后使用注冊的賬號密碼進(jìn)行系統(tǒng)登錄并使用。密碼采用MD5密文保存到數(shù)據(jù)庫中,確保用戶的隱私安全。
          • 場地展示:系統(tǒng)從數(shù)據(jù)庫讀取當(dāng)前的場地信息,如場地類型、場地的名稱、是否空閑等信息。并將其展示到頁面前臺,供用戶查看選擇。
          • 預(yù)約:用戶根據(jù)自己需要的場地類型,選擇合適的場地,選中后系統(tǒng)顯示該場地已被預(yù)約的時(shí)段,避免產(chǎn)生沖突。用戶選擇好時(shí)間段以后即可進(jìn)行預(yù)約,系統(tǒng)檢測預(yù)約是否沖突,如果不沖突則預(yù)約成功。
          • 取消預(yù)約:展示用戶已經(jīng)預(yù)約成功的場地和時(shí)段,用戶不需要了可以取消預(yù)約。
          • 歷史展示:顯示用戶的歷史預(yù)約記錄。

          該系統(tǒng)的應(yīng)用群體主要為大學(xué)生和大學(xué)教師。場景面向大學(xué)校園。旨在打造一個方便的場地預(yù)約管理系統(tǒng)。

          2、設(shè)計(jì)思路

          系統(tǒng)的設(shè)計(jì)分為前端、后端和數(shù)據(jù)庫三大塊。初步確定的開發(fā)平臺為微軟的.net平臺+SQL Sever數(shù)據(jù)庫(當(dāng)然也是課程設(shè)計(jì)要求的)。前端對相關(guān)的頁面進(jìn)行設(shè)計(jì)布局,還可以使用現(xiàn)成的CSS框架進(jìn)行一定的美化。后端可以使用老師封裝好的SqlHelper.cs進(jìn)行數(shù)據(jù)庫的一些請求。前后端交互采用的主要是AJAX技術(shù),實(shí)現(xiàn)輕量級的交互。關(guān)于前后端主要的思路如下:

          • 前端:分頁面進(jìn)行開發(fā),可以使得結(jié)構(gòu)更加清晰。頁面可劃分為登錄注冊頁面和主功能頁面。
          • 后端:交互技術(shù)使用AJAX進(jìn)行交互,后端可以使用.ashx文件進(jìn)行API的編寫,采用參數(shù)action控制請求的類型,例如action=”login”時(shí)表示請求的是登錄功能,從而進(jìn)行判斷。
          • 數(shù)據(jù)庫:確定系統(tǒng)的功能,提取相應(yīng)的數(shù)據(jù)結(jié)構(gòu),建立數(shù)據(jù)庫表。系統(tǒng)功能結(jié)構(gòu)設(shè)計(jì)圖如下:
          575469dcf4c6e15ab4216fcebef12f64.webp

          3、關(guān)鍵問題與實(shí)現(xiàn)代碼

          在該系統(tǒng)中,關(guān)鍵性的問題主要有以下幾個:

          (1)AJAX接口的設(shè)計(jì)問題,項(xiàng)目屬于輕量級項(xiàng)目,不需要多個后臺接口文件(.ashx),避免造成管理上的不便。采用一個.ashx實(shí)現(xiàn)多個請求,需要在請求時(shí)加上該請求所需要的功能,即action參數(shù)。因此采用了以下的框架:

          public?void?ProcessRequest(HttpContext?context)
          ????????{
          ????????????context.Response.ContentType?=?"text/plain";
          ????????????string?action?=?context.Request["action"];
          ????????????if?(!string.IsNullOrEmpty(action))
          ????????????{
          ????????????????switch?(action)
          ????????????????{
          ????????????????????case?"bookRoom":

          在開頭便判斷Request的action參數(shù),確定該請求所需要的功能,然后調(diào)用相應(yīng)的代碼進(jìn)行Response。

          (2)利用請求返回的json數(shù)據(jù)創(chuàng)建相應(yīng)的HTML代碼,顯示到頁面上。以場地信息的展示為例:

          后臺代碼:

          case?"flushRoom":
          ????DataTable?dtRoom?=?SqlHelper.getDataTable("select?*?from?RoomInfo");
          ????string?sJson?=?JsonConvert.SerializeObject(dtRoom);
          ????context.Response.Write(sJson);
          ????break;

          使用sql語句獲取所有記錄,轉(zhuǎn)為json字符串以后返回到前臺。前臺AJAX請求代碼:

          function?flushRoom()?{
          ????????$.ajax({
          ????????????type:?'get',
          ????????????url:?'RoomBookHandler.ashx',
          ????????????async:?true,
          ????????????data:?{
          ????????????????action:?'flushRoom',
          ????????????},
          ????????????success:?function?(result)?{
          ????????????????document.getElementById("roomInfo").innerHTML?=?creatRoomTable(result);
          ????????????????var?footerStr?=?'<footer?id="bookTimeSpan"?></footer?>';
          ????????????????document.getElementById("bookTimeSpan").innerHTML?=?footerStr;
          ????????????},
          ????????????error:?function?()?{
          ????????????????alert('獲取數(shù)據(jù)失敗!');
          ????????????}
          ????????});
          ????}

          將AJAX返回的結(jié)果,使用creatRoomTable函數(shù)生成HTML表格,并設(shè)置到頁面的元素上面。creatRoomTable的代碼如下:

          function?creatRoomTable(dataStr)?{
          ????????var?dataList?=?JSON.parse(dataStr);
          ????????var?trStr?=?'<table?class="primary"?id="roomInfo"?style="width:?100%"><tr>'?+
          ????????????'<th>?教室號</th>?<th>教室類型</th><th>容納人數(shù)</th>'?+
          ????????????'<th>?教室狀態(tài)</th>?<th>教室說明</th><th>是否預(yù)約</th></tr?>';
          ????????//循環(huán)遍歷出json對象中的每一個數(shù)據(jù)并顯示在對應(yīng)的td中
          ????????for?(i?=?0;?i?<?dataList.length;?i++)?{
          ????????????trStr?+=?'<tr>';
          ????????????trStr?+=?'<td>'?+?dataList[i].RoomNumber?+?'</td>';
          ????????????trStr?+=?'<td>'?+?dataList[i].RoomType?+?'</td>';
          ????????????trStr?+=?'<td>'?+?dataList[i].RoomPeople?+?'</td>';
          ????????????trStr?+=?'<td>'?+?dataList[i].RoomStatus?+?'</td>';
          ????????????trStr?+=?'<td>'?+?dataList[i].Remarks?+?'</td>';
          ????????????trStr?+=?'<td>';
          ????????????if?(dataList[i].RoomStatus.toString().trim()?===?"空閑")?{
          ????????????????trStr?+=?'<label><input?type="radio"?onClick="getRoomTimeSpan()"?name="selectRoom"?value="'?+?dataList[i].RoomNumber.toString()?+?'"?/><span class="checkable">預(yù)定</span></label>';
          ????????????}
          ????????????else?{
          ????????????????trStr?+=?"不可用";
          ????????????}
          ????????????trStr?+=?'</td>';
          ????????????trStr?+=?'</tr>';
          ????????}
          ????????trStr?+=?'</table>'
          ????????return?trStr;
          ????}

          首先需要將字符串轉(zhuǎn)成json對象,隨后構(gòu)建表格的HTML代碼,遍歷json對象逐個生成表格元素。

          (3)檢測預(yù)約時(shí)間段是否重復(fù)。數(shù)據(jù)庫中存儲的時(shí)間段是以字符串形式存儲的,其實(shí)判斷區(qū)間有無重復(fù)可以直接對字符串進(jìn)行比較。思路是先檢索該場地已預(yù)約的時(shí)間段。隨后一一進(jìn)行對比,如果全部通過,則不存在沖突。檢測的思路如下圖所示:

          25cb6c8f81925db33e87f4326ed6e896.webp

          只需要判斷新的預(yù)約是否在已預(yù)約時(shí)間段的左側(cè)或者右側(cè)即可。具體的代碼如下:

          for?(int?i?=?0;?i?<?dtBookInfo.Rows.Count;?i++)
          {
          ????//大于已預(yù)約右邊,小于已預(yù)約左邊
          ????notOverlap?&=?(?(string.Compare(bookSt,?dtBookInfo.Rows[i][1].ToString().Trim(),?true)?>?0)?||
          ????????????????????(string.Compare(bookEt,?dtBookInfo.Rows[i][0].ToString().Trim(),?true)?<?0)?);
          }
          if?(!notOverlap)
          {
          ????context.Response.Write("該時(shí)間段已經(jīng)有別人預(yù)約啦,請重新選擇!");
          }

          4、數(shù)據(jù)庫結(jié)構(gòu)

          數(shù)據(jù)庫的設(shè)計(jì)中,使用了三個數(shù)據(jù)庫表用以系統(tǒng)數(shù)據(jù)的存儲。分別為:

          • RoomInfo:記錄場地的信息,諸如場地類型,容納人數(shù),是否可用等。
          • BookInfo:記錄預(yù)定的信息,例如預(yù)定的用戶,預(yù)定的場地,預(yù)定的時(shí)間段等。
          • WebUser:記錄系統(tǒng)的用戶信息,如用戶名,密碼的MD5密文,手機(jī)號等。

          RoomInfo表的結(jié)構(gòu)如下:

          列名數(shù)據(jù)類型說明實(shí)例
          RoomNumbernchar(10)場地號東九A101
          RoomTypenchar(10)場地類型階梯教室
          RoomPeoplenchar(10)場地能容納的人數(shù)100
          RoomStatusnchar(10)場地狀態(tài)空閑
          Remarksnchar(10)備注正在裝修

          BookInfo表的結(jié)構(gòu)如下:

          列名數(shù)據(jù)類型說明實(shí)例
          IDint預(yù)定號1
          CustomerNamevarchar(255)用戶名張三
          MyRemarknvarchar(50)備注預(yù)定教室開班會
          BookDatenchar(10)預(yù)定日期2021-06-01
          BookStnchar(50)預(yù)定開始時(shí)間09:30
          BookEtnchar(50)預(yù)定結(jié)束時(shí)間11:20
          BookDurationfloat預(yù)定時(shí)長2.5
          RoomNumbernchar(10)預(yù)定的場地號東九A101

          WebUser表的結(jié)構(gòu)如下:

          列名數(shù)據(jù)類型說明實(shí)例
          usernamevarchar(255)用戶名張三
          passwordvarchar(255)密碼MD5202……
          telephonevarchar(50)電話17798253366

          數(shù)據(jù)庫的ER圖如下:

          436f5225bc5b5ba4fbce067cd95f41a1.webp

          5、程序主要代碼及其說明

          項(xiàng)目結(jié)構(gòu)如下,css、js等文件都放入了相應(yīng)的文件夾。前端分為登錄注冊頁面(login.aspx)和預(yù)定頁面(indextem.aspx)。用到了一些幫助類(SqlHelper.cs等):

          400551cce0651131b4d2efaebb197540.webp

          5.1 前端

          前端開發(fā)時(shí),JavaScript部分用到了json3和jQuery的庫,需要在aspx文件開頭中引入:

          <script?src="https://cdn.bootcss.com/json3/3.3.2/json3.js"></script>
          <script?src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

          前端的界面使用了一個小型而時(shí)尚CSS庫Picnic CSS(https://picnicss.com/) 進(jìn)行美化,并且自定義了一些css的樣式,需要在頭部引入相關(guān)文件:

          <link?rel="stylesheet"?href="css/templatemo-style.css"?/>
          <link?rel="stylesheet"?href="css/picnic.css"?/>

          登錄頁面

          48a68b41c3b05ac45b66851aec26e99b.webp

          登錄頁面需要在成功以后做跳轉(zhuǎn),因此采用的是form提交的信息:

          <div?id="section1"?class="section-w3ls">
          ????<input?type="radio"?name="sections"?id="option1"?checked>
          ????<label?for="option1"?class="icon-left-w3pvt"><span class="fa?fa-user-circle"?aria-hidden="true"></span>登錄</label>
          ????<article>
          ????????<form?runat="server">
          ????????????<h3?class="legend">賬號登錄</h3>
          ????????????<div?class="input">
          ????????????????<span class="fa?fa-user-o"?aria-hidden="true"></span>
          ????????????????<input?type="text"?placeholder="用戶名"?name="inputEmail"?required?/>
          ????????????</div>
          ????????????<div?class="input">
          ????????????????<span class="fa?fa-key"?aria-hidden="true"></span>
          ????????????????<input?type="password"?placeholder="密碼"?name="inputPassword"?required?/>
          ????????????</div>
          ????????????<asp:Button?ID="Button1"?class="btn?submit"?runat="server"?Text="登陸"?OnClick="Button1_Click"?/>
          ????????????<a?href="#"?class="bottom-text-w3ls">忘記密碼?</a>
          ????????</form>
          ????</article>
          </div>

          注冊用戶進(jìn)行用戶名的檢測:

          8f9ed48923b4f01db622a65241d5f462.webpab51f9994c6f75f930b2c8b46b12b667.webp

          預(yù)約頁面

          預(yù)約頁面需要顯示的信息較多,如下圖所示:

          28b4ad0cef2a666e975037aac5a327f8.webp

          可以在HTML頁面編寫元素,然后使用js動態(tài)生成,例如:

          <table?class="primary"?id="roomInfo"?style="width:?100%"></table>

          document.getElementById("roomInfo").innerHTML?=?creatRoomTable(result);

          也可以直接在aspx文件中使用C#的腳本進(jìn)行生成:

          <%
          System.Data.DataSet?ds2?=?MyDBUtils.DBHelper.ExecuteQuery("select?BookInfo.ID,?BookInfo.RoomNumber,?RoomType,?RoomPeople,?MyRemark,BookSt,?"?+
          ????"BookEt,?BookDuration?from?BookInfo?join?RoomInfo?on?"?+
          ????"BookInfo.RoomNumber?=?RoomInfo.RoomNumber?where?"?+
          ????"BookDate?>?'"?+?DateTime.Now.ToString("yyyy-MM-dd")?+?"'?and?CustomerName='"?+?Request.Cookies["login_name"].Value?+?"'");
          for?(int?i?=?0;?i?<?ds2.Tables[0].Rows.Count;?i++)
          {
          ????Context.Response.Write("<tr>");

          ????for?(int?j?=?1;?j?<?8;?j++)
          ????{
          ????????Context.Response.Write("<td>");
          ????????Context.Response.Write(ds2.Tables[0].Rows[i][j].ToString());
          ????????Context.Response.Write("</td>");
          ????}
          ????Context.Response.Write("<td>");
          ????Context.Response.Write("<label><input?type='checkbox'?name='checkbokRoom'?value='"?+?ds2.Tables[0].Rows[i][0].ToString()+"-"+?ds2.Tables[0].Rows[i][1].ToString()?+?"'?/><span class='checkable'>退訂</span></label>");
          ????Context.Response.Write("</td>");
          ????Context.Response.Write("</tr>");
          }
          %>

          表格中的radio單選按鈕,需要綁定單擊的事件,這部分代碼獲取選中的場地所預(yù)約的時(shí)間段,并將其顯示到表格下方的框框中,為AJAX局部更新,改變選中的場地時(shí)(單選按鈕的改變),也會在下面更新該場地的預(yù)約時(shí)間段:

          function?getRoomTimeSpan()?{
          ??var?roomNumber?=?getSelectedRadioValue();
          ??//發(fā)送請求獲預(yù)約的時(shí)間段
          ??$.ajax({
          ??????type:?'get',
          ??????url:?'RoomBookHandler.ashx',
          ??????async:?true,
          ??????data:?{
          ??????????action:?'getBookTime',
          ??????????roomNo:?roomNumber
          ??????},
          ??????success:?function?(result)?{
          ??????????var?dataList?=?JSON.parse(result);
          ??????????var?footerStr?=?'<footer?id="bookTimeSpan"?>';
          ??????????for?(var?ind?in?dataList)?{
          ??????????????footerStr?+=?'<span class="label?warning"?style="font-size:?110%">';
          ??????????????footerStr?+=?dataList[ind].BookSt.toString().trim().substring(0,?5);
          ??????????????footerStr?+=?'?-?';
          ??????????????footerStr?+=?dataList[ind].BookEt.toString().trim().substring(0,?5);
          ??????????????footerStr?+=?'</span >';
          ??????????}
          ??????????footerStr?+=?'</footer?>';
          ??????????document.getElementById("bookTimeSpan").innerHTML?=?footerStr;
          ??????},
          ??????error:?function?()?{
          ??????????alert('獲取數(shù)據(jù)失敗!');
          ??????}
          ??});
          }

          時(shí)間段的選擇使用了一個時(shí)間選擇控件,效果如下:

          b3ad2ebc10f7155ea392bf48e50d3b94.webp

          預(yù)定時(shí),獲取用戶輸入的一系列數(shù)據(jù),然后使用AJAX發(fā)送到后臺進(jìn)行處理:

          function?bookRoom()?{
          ????var?bookT?=?document.getElementById("timeArrange").value;
          ????if?(bookT?===?"")?{
          ????????alert("必須選擇要借用的時(shí)間范圍!");
          ????????return?false;
          ????}
          ????var?myR?=?document.getElementById("myRemarks").value;
          ????var?roomNumber?=?getSelectedRadioValue();
          ????if?(roomNumber?===?"")?{
          ????????alert("必須選擇要借用的教室!");
          ????????return?false;
          ????}
          ????//要發(fā)送的數(shù)據(jù),教室號,預(yù)定開始時(shí)間-結(jié)束時(shí)間,我的備注

          ????$.ajax({
          ????????type:?'post',
          ????????url:?'RoomBookHandler.ashx',
          ????????async:?true,
          ????????data:?{
          ????????????action:?'bookRoom',
          ????????????roomNo:?roomNumber,
          ????????????bookTime:?bookT,
          ????????????myRemark:?myR
          ????????},
          ????????success:?function?(result)?{
          ????????????alert(result);
          ????????????getRoomTimeSpan();
          ????????????updateBookedTable();
          ????????},
          ????????error:?function?()?{
          ????????????alert('請求失敗!');
          ????????}
          ????});
          }

          注意,如果用戶輸入不合法,比如未選中時(shí)間段,未選中教室,時(shí)間段沖突等都無法有效完成預(yù)定。

          預(yù)約成功顯示預(yù)約的教室:

          601bc7e3e7ad1a63313240d6f6c96452.webp

          表格創(chuàng)建代碼與場地顯示的表格創(chuàng)建代碼類似,取消預(yù)約的需要將取消的預(yù)定號(預(yù)定號綁定到了checkbox的value中)發(fā)送到后臺,進(jìn)行記錄刪除:

          function?cancelBook()?{
          ????var?checkList?=?[];
          ????var?timeSpanUpList?=?[];
          ????var?checkbokContext?=?document.getElementsByName("checkbokRoom");
          ????for?(i?=?0;?i?<?checkbokContext.length;?++i)?{
          ????????if?(checkbokContext[i].checked)?{
          ????????????var?dataStr?=?checkbokContext[i].value.split('-');
          ????????????checkList.push(dataStr[0]);
          ????????????timeSpanUpList.push(dataStr[1]);
          ????????}
          ????}
          ????if?(checkList.length?==?0)?{
          ????????alert("請選擇您需要取消預(yù)約的教室!");
          ????????return?false;
          ????}
          ????var?cancelListStr?=?checkList.join(',');?//轉(zhuǎn)成1,3,4這種形式,后臺再解析
          ????$.ajax({
          ????????type:?'post',
          ????????url:?'RoomBookHandler.ashx',
          ????????async:?true,
          ????????data:?{
          ????????????action:?'cancelBook',
          ????????????cancel:?cancelListStr
          ????????},
          ????????success:?function?(result)?{
          ????????????alert(result);
          ????????????//刷新本表
          ????????????updateBookedTable();
          ????????????//刷新foot
          ????????????if?(timeSpanUpList.indexOf(getSelectedRadioValue())?!=?-1)?{
          ????????????????getRoomTimeSpan();
          ????????????}
          ????????},
          ????????error:?function?()?{
          ????????????alert('連接失敗!');
          ????????}
          ????});
          }

          成功以后,更新該表格。但是需要注意的是,此外還做了一個小細(xì)節(jié),取消某一時(shí)間段以后,如果恰好在場地展示頁面選中的也是這個教室,那么下面的預(yù)約時(shí)間段也會同步更新,采用的同樣為AJAX技術(shù)。

          8ce71e34e0afc0ad0595f3a376057c01.webp
          success:?function?(result)?{
          ????alert(result);
          ????//刷新本表
          ????updateBookedTable();
          ????//刷新foot
          ????if?(timeSpanUpList.indexOf(getSelectedRadioValue())?!=?-1)?{
          ????????getRoomTimeSpan();
          ????}
          },

          歷史預(yù)約表格的生成,采用的是aspx中嵌入腳本的形式生成的:

          e9e99803fda0ea828148dce3209c260a.webp
          <table?class="primary"??style="width:?100%">
          ????<tr>
          ????????<th>教室號</th>
          ????????<th>教室類型</th>
          ????????<th>容納人數(shù)</th>
          ????????<th>我的備注</th>
          ????????<th>日期</th>
          ????????<th>開始時(shí)間</th>
          ????????<th>結(jié)束時(shí)間</th>
          ????????<th>借用時(shí)長(小時(shí))</th>
          ????</tr>
          ????<tbody>
          ????<%
          ????????System.Data.DataSet?ds3?=?MyDBUtils.DBHelper.ExecuteQuery("select?BookInfo.RoomNumber,?RoomType,?RoomPeople,?MyRemark,BookDate,BookSt,?"?+
          ????????????"BookEt,?BookDuration?from?BookInfo?join?RoomInfo?on?"?+
          ????????????"BookInfo.RoomNumber?=?RoomInfo.RoomNumber?"?+
          ????????????"where?BookDate?<?'"?+?DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")?+"'?and?CustomerName='"?+?Request.Cookies["login_name"].Value?+?"'");
          ????????for?(int?i?=?0;?i?<?ds3.Tables[0].Rows.Count;?i++)
          ????????{
          ????????????Context.Response.Write("<tr>
          ");

          ????????????for?(int?j?=?0;?j?<?8;?j++)
          ????????????{
          ????????????????Context.Response.Write("<td>
          ");
          ????????????????Context.Response.Write(ds3.Tables[0].Rows[i][j].ToString());
          ????????????????Context.Response.Write("</td>");
          ????????????}
          ????????????Context.Response.Write("</tr>");
          ????????}
          ????%>
          ????</tbody>
          </table>

          檢索的時(shí)候,系統(tǒng)將自動從預(yù)訂表中檢索該用戶在今天之前的預(yù)約信息,并展示出來。

          5.2 后臺

          登錄頁面

          后臺代碼進(jìn)行校驗(yàn),需要先將密碼轉(zhuǎn)成MD5密文,然后實(shí)行字符串匹配:

          string?username?=?Request.Params["inputEmail"].ToString();
          string?password?=?MD5Helper.ToMD5(Request.Params["inputPassword"].ToString());

          if?(DBHelper.ExecuteQuery("select?*?from?WebUser?where?username='"?+?username?+?"'?and?password='"?+?password?+?"'").Tables[0].Rows.Count?>?0)
          {
          ????//放一個Cookie來指示是哪名用戶登陸了
          ????HttpCookie?cookie?=?new?HttpCookie("login_name",?username);
          ????Response.Cookies.Add(cookie);
          ????Response.Redirect("indextem.aspx");
          }
          else
          {
          ????Response.Write("<script?language=javascript>alert('用戶名或密碼錯誤');</script>");
          }

          注冊頁面的前端類似,后端代碼以數(shù)據(jù)庫插入為主,需要判斷用戶名是否重復(fù),如下:

          var?name?=?Request["regName"];
          if?(!string.IsNullOrEmpty(name))
          {
          ????if?(DBHelper.ExecuteQuery("select?*?from?WebUser?where?username='"?+?name?+?"'").Tables[0].Rows.Count?>?0)
          ????{
          ????????//檢測該用戶名是否注冊
          ????????Response.Write("<script language=javascript>alert('注冊失敗,用戶名已被使用!');</script>");
          ????}
          ????else
          ????{
          ????????var?passwd?=?Request["regPassword"];
          ????????passwd?=?MD5Helper.ToMD5(passwd.ToString());
          ????????var?telephone?=?Request["regTelephone"];
          ????????var?sql?=?"INSERT?INTO?WebUser(username,password,telephone)?VALUES?('{0}','{1}','{2}')";
          ????????sql?=?string.Format(sql,?name,?passwd,?telephone);
          ????????if?(SqlHelper.ExecuteSql(sql)?>?0)
          ????????{
          ????????????var?str?=?"注冊成功,您的用戶名:"?+?name?+?"?,現(xiàn)在去登錄試試吧~";
          ????????????Response.Write("<script?language=javascript>alert('"?+?str?+?"');</script>");
          ????????}
          ????????else
          ????????{
          ????????????Response.Write("<script language=javascript>alert('注冊失敗,數(shù)據(jù)庫出錯!');</script>");
          ????????}
          ????}
          }

          預(yù)約頁面

          預(yù)定的后臺處理代碼,后臺需要做預(yù)定沖突的檢測:

          string[]?bookTime?=?context.Request["bookTime"].Split('-');
          string?bookSt?=?bookTime[0].Trim();
          string?bookEt?=?bookTime[1].Trim();
          string?bookDate?=?DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");
          string?roomNumber?=?context.Request["roomNo"];
          //預(yù)定時(shí)間區(qū)間判斷
          var?bookInfoSql?=?"select?BookSt,?BookSt?from?BookInfo?where?"?+
          ????"BookDate='{0}'?And?RoomNumber='{1}'";
          bookInfoSql?=?string.Format(bookInfoSql,?bookDate,?roomNumber);
          DataTable?dtBookInfo?=?SqlHelper.getDataTable(bookInfoSql);
          Boolean?notOverlap?=?true;
          for?(int?i?=?0;?i?<?dtBookInfo.Rows.Count;?i++)
          {
          ????//大于已預(yù)約右邊,小于已預(yù)約左邊
          ????notOverlap?&=?(?(string.Compare(bookSt,?dtBookInfo.Rows[i][1].ToString().Trim(),?true)?>?0)?||
          ????????????????????(string.Compare(bookEt,?dtBookInfo.Rows[i][0].ToString().Trim(),?true)?<?0)?);
          }
          if?(!notOverlap)
          {
          ????context.Response.Write("該時(shí)間段已經(jīng)有別人預(yù)約啦,請重新選擇!");
          }
          else
          {
          ????string?customerName?=?context.Request.Cookies["login_name"].Value;
          ????string?myRemark?=?context.Request["myRemark"];
          ????if?(string.IsNullOrEmpty(myRemark))
          ????{
          ????????myRemark?=?"無";
          ????}

          ????DateTime?dt1?=?DateTime.Parse(bookDate?+?"?"?+?bookSt);
          ????DateTime?dt2?=?DateTime.Parse(bookDate?+?"?"?+?bookEt);
          ????TimeSpan?ts?=?dt2.Subtract(dt1);
          ????double?bookDurationHours?=?Math.Round(ts.TotalHours,?2);

          ????DataTable?dtLastID?=?SqlHelper.getDataTable("select?top?1?ID?from?BookInfo?order?by?ID?DESC");
          ????string?insIdStr?=?dtLastID.Rows[0][0].ToString();
          ????int?insId?=?int.Parse(insIdStr)?+?1;
          ????//插入到數(shù)據(jù)庫中去
          ????var?bookSql?=?"INSERT?INTO?BookInfo(ID,?CustomerName,MyRemark,BookDate,BookSt,BookDuration,RoomNumber,BookEt)?"?+
          ????????"VALUES?({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}')";
          ????bookSql?=?string.Format(bookSql,?insId,?customerName,?myRemark,?bookDate,?bookSt,?bookDurationHours,
          ????????roomNumber,?bookEt);
          ????if?(SqlHelper.ExecuteSql(bookSql)?>?0)
          ????{
          ????????context.Response.Write("預(yù)定成功!");
          ????}
          ????else
          ????{
          ????????context.Response.Write("后臺數(shù)據(jù)插入出錯!");
          ????}
          }

          獲取預(yù)訂時(shí)間段后臺處理代碼:

          string?roomNum?=?context.Request["roomNo"];
          var?sqlBookSp?=?"select?BookSt,?BookEt?from?BookInfo?"?+
          ????"where?BookDate?=?'"?+?DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")?+?"'?and?RoomNumber?=?'{0}'?order?by?BookSt";
          sqlBookSp?=?string.Format(sqlBookSp,?roomNum);
          DataTable?dtTimeSp?=?SqlHelper.getDataTable(sqlBookSp);
          string?sJson2?=?JsonConvert.SerializeObject(dtTimeSp);
          context.Response.Write(sJson2);
          break;

          取消預(yù)約的代碼:

          //刪除預(yù)訂的數(shù)據(jù)
          string[]?delListStr?=?context.Request["cancel"].Split(',');
          int?totalCancel?=?0;
          foreach(var?delRoom?in?delListStr)
          {
          ??var?delSql?=?"delete?from?BookInfo?where?ID?=?"?+?delRoom;
          ??if?(SqlHelper.ExecuteSql(delSql)?>?0)
          ??{
          ??????
          ??????totalCancel++;
          ??}
          }
          context.Response.Write("取消預(yù)訂完成,共取消?"?+?totalCancel.ToString()?+?"?間教室!");

          6、運(yùn)行效果圖

          登錄

          0fa359ad8fe3dcfd59f400fc79b6a9be.webp

          注冊:

          ea55821e14f82debd84ef06ff87949e5.webpe2b46f9fbb4f6794b57b38f62b85005e.webp

          預(yù)訂(可以手動刷新教室信息):

          e9400b49e43bda286c4f01347d622e4d.webp99b221e50a171fc6844fde8546d512d8.webpc0757fb85098f4e6a3d669d1f721a246.webpae17cc89019d453252077c36b249eb02.webp

          時(shí)間沖突:

          4312b9fc120d1e55662562c4daba18b6.webp

          我的預(yù)訂:

          895c568e8f245c7cd49ea0a6a51ec071.webp

          取消預(yù)訂(支持多個一起取消):

          136fb6f968325bee5e687b6cf436270e.webp

          取消以后自動刷新該場地下預(yù)約的時(shí)間段:

          4af1f95aeee4a80ce0c999e371e632a8.webp

          歷史預(yù)約 && 我的信息顯示:

          09e6fb0a4295d846db8c2e72924179ec.webp

          7、小結(jié)

          場地信息的發(fā)布應(yīng)該還需要一個管理端,即管理員可以編輯場地信息,然后進(jìn)行發(fā)布,但是由于個人能力有限,管理端沒有進(jìn)行設(shè)計(jì)。或者將系統(tǒng)與hub直接對接,檢索空閑的教室場地等進(jìn)行借用,也是可以的。不過需要學(xué)校方面的支持。

          附錄

          數(shù)據(jù)庫腳本【已附在程序目錄】運(yùn)行時(shí)可能需要修改文件存儲目錄,默認(rèn)為D盤下的DataBase文件夾:

          4b799df7e8a79f5631d0408a607c3be4.webp

          利用VS2019及其以上版本打開項(xiàng)目文件.sln:

          e7e2eb41b8fbbd7b810ecfd8168f47a3.webp

          運(yùn)行l(wèi)ogin.aspx即可:

          5e295f674a55e40ca4c775cc962ebf72.webp


          瀏覽 67
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91丨九色丨蝌蚪丨成人 | 成人网站在线精品国产免费 | 一级黄片免费 | 青青草成人在线免费观看视频 | 成人做爰黄 片视频动漫 |