這邊題目給出的指示需要摸擬一個影廳的座位狀況,然後使用者可以點選座位來訂票,所以會需要一些建置前端頁面的工作;
這邊會先由前端頁面使用ajax來傳送電影id,日期,場次等資訊到api,然後在api程式中使用php來取出已訂位的資料,建置完座位區後,再以js來完成前端劃位的操作,最後再把訂單資料送到後端去儲存,完成整個訂票的功能。
頁面切換機制
- 在劃位的功能的處理上,我們不使用表單跳頁的方式,而是使用js來控制畫面區塊的切換,這樣就能保留表單的選擇狀態,回上一步時只要切換區塊即可。
- 我們也同時使用ajax的方式把選單的內容傳送到後端去產生一份劃位的頁面,並放在
#booking
區塊中
./front/order.php1
2
3
4
5<div class="ct">
<!--點擊選單的確定時,讓兩個div的顯示狀態切換,同時也向後端取得劃位畫面-->
<button onclick="booking()">確定</button>
<button>重置</button>
</div>
1 | function booking(){ |
劃位頁面製作
劃位頁面的產生及劃位行為應該是本題組最複雜的一部份了,這邊要注意的細節比較多,同時也有很多的技巧用來簡化程式碼的撰寫。
接著我們建立劃位頁面的架構,並建立必要的class name
./api/booking.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36<div id="room">
<!--建立一個容器來存放所有的座位-->
<div class="seats">
<?php
for($i=0;$i<20;$i++){
//建立一個座位的容器
echo "<div class='seat'>";
//座位文字置中
echo "<div class='ct'>";
//計算第幾排
echo (floor($i/5)+1) . "排";
//計算第幾個位置
echo (($i%5)+1) . "號";
echo "</div>";
//座位圖置中
echo "<div class='ct'>";
echo "<img src='./icon/03D02.png'>";
echo "</div>";
//座位勾選欄位
echo "<input type='checkbox' name='chk' value='$i' class='chk'>";
echo "</div>";
}
</div>
</div>
<div id="info">
<div>您選擇的電影是:</div>
<div>您選擇的時刻是:</div>
<div>您已經勾選<span id='tickets'>0</span>張票,最多可以購買四張票</div>
<div>
<!--使用jquery來切換顯示區塊-->
<button onclick="$('#select').show();$('#booking').hide()">上一步</button>
<button onclick="checkout()">訂購</button>
</div>
</div>建立劃位頁面的css設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#room{
background-image: url('./icon/03D04.png');
background-position: center;
background-repeat: none;
width:540px;
height:370px;
margin:auto;
box-sizing: border-box;
padding:19px 112px 0 112px;
}
.seat {
width: 63px;
height: 85px;
position: relative;
}
.seats {
display: flex;
flex-wrap: wrap;
}
.chk{
position: absolute;
right:2px;
bottom:2px;
}根據前端ajax傳來的資料取得劃位頁面需要的內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23include_once "db.php";
// 根據電影id取得電影資料
$movie=$Movie->find($_GET['movie_id']);
// 取得訂購電影的日期
$date=$_GET['date'];
// 取得訂購電影的場次
$session=$_GET['session'];
// 取得符合條件場次的所有訂單資料
$ords=$Order->all(['movie'=>$movie['name'],
'date'=>$date,
'session'=>$session]);
// 先建立一個空陣列來存放所有訂單的座位資料
$seats=[];
// 將所有訂單的座位資料合併到$seats陣列中
foreach($ords as $ord){
// 將座位資料反序列化後合併到$seats陣列中
$tmp=unserialize($ord['seats']);
$seats=array_merge($seats,$tmp);
}在座位的迴圈中增加對於已訂座位的判斷,並顯示已訂位圖示及不顯示勾選欄位
./api/booking.php1
2
3
4
5
6
7
8
9
10echo "<div class='ct'>";
if(in_array($i,$seats)){
echo "<img src='./icon/03D03.png'>";
}else{
echo "<img src='./icon/03D02.png'>";
}
echo "</div>";
if(!in_array($i,$seats)){
echo "<input type='checkbox' name='chk' value='$i' class='chk'>";
}根據ajax傳來的資訊,將訂位資訊顯示在下方訂票資訊區
1
2
3
4
5
6
7
8
9<div id="info">
<div>您選擇的電影是:$movie['name']; </div>
<div>您選擇的時刻是:$date; $session; </div>
<div>您已經勾選<span id='tickets'>0</span>張票,最多可以購買四張票</div>
<div>
<button onclick="$('#select').show();$('#booking').hide()">上一步</button>
<button onclick="checkout()">訂購</button>
</div>
</div>撰寫訂位行為的js程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34//建立一個js陣列用來儲存使用者選中的座位
let seats=new Array();
//監聽checkbox的改變事件
$(".chk").on("change",function(){
//根據屬性checked的狀態來決定下一步是選擇位置還是取消位置
if($(this).prop('checked')){
//如果是選中的狀態,
//先判斷目前選中的座位有沒有超過四個
if(seats.length+1<=4){
//如果選中的座位數還沒有超過四個,
//就把座位號碼放入陣列中
seats.push($(this).val())
}else{
//接著將選中的座位還原為不選中的狀態
$(this).prop('checked',false)
//如果選中的座位已經四張了,就會出現警告
alert("每個人只能勾選四張票")
}
}else{
//如果是要取消選中的座位,
//則同時也在座位陣列中移除該座位號碼
seats.splice(seats.indexOf($(this).val()),1)
}
//更新票數的文字內容
$("#tickets").text(seats.length)
})撰寫送出訂單函式
1
2
3
4
5
6
7
8
9
10
11
12
13
14//確認訂單的函式
function checkout(){
//使用ajax向api傳送訂單的資料
$.post("./api/checkout.php",
{movie:'<?=$movie['name'];?>',
date:'<?=$date;?>',
session:'<?=$session;?>',
qt:seats.length,
seats},
(no)=>{
//如果訂單成功,就將網址導向到訂單資料頁面,並帶上訂單編號
location.href=`?do=result&no=${no}`;
})
}撰寫後端儲存訂單資料的程式
./api/checkout.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19include_once "db.php";
//先將座位陣列排序過
sort($_POST['seats']);
//將陣列轉成格式化的字串
$_POST['seats']=serialize($_POST['seats']);
//取得資料的id值用來製作編號
$id=$Order->max('id')+1;
//產生有流水號性質的訂單編號
$_POST['no']=date("Ymd").sprintf("%04d",$id);
//將$_POST新增進資料表
$Order->save($_POST);
//回傳訂單編號
echo $_POST['no'];最後是製作訂單結果頁面,我們在劃位的最後按下訂購時,透過ajax取得訂單編號,同時將頁面導向訂單結果頁面,再利用訂單編號取得訂單資料,來產生訂單結果頁面。
./front/result.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//根據訂單編號取得訂單資料
$order=$Order->find(['no'=>$_GET['no']]);
<table>
<tr>
<td colspan='2'>感謝您的訂購,您的訂單編號是:$_GET['no']; </td>
</tr>
<tr>
<td>電影名稱:</td>
<td>$order['movie']; </td>
</tr>
<tr>
<td>日期:</td>
<td>$order['date']; </td>
</tr>
<tr>
<td>場次時間:</td>
<td>$order['session']; </td>
</tr>
<tr>
<td colspan='2'>
座位:<br>
//將座位資料轉成陣列
$seats=unserialize($order['seats']);
//印出每一個座位
foreach($seats as $seat){
//計算排數與號碼
echo (floor($seat/5)+1) . "排";
echo (($seat%5)+1) . "號";
echo "<br>";
}
echo "共{$order['qt']}張電影票"
</td>
</tr>
</table>
<div class="ct">
<!--按下確定按鈕時將使用者導回首頁-->
<button onclick="location.href='index.php'">確認</button>
</div>