0%

[技能檢定]題組三 步驟17 前台線上訂票功能-劃位功能及訂票完成

這邊題目給出的指示需要摸擬一個影廳的座位狀況,然後使用者可以點選座位來訂票,所以會需要一些建置前端頁面的工作;

這邊會先由前端頁面使用ajax來傳送電影id,日期,場次等資訊到api,然後在api程式中使用php來取出已訂位的資料,建置完座位區後,再以js來完成前端劃位的操作,最後再把訂單資料送到後端去儲存,完成整個訂票的功能。

頁面切換機制

  1. 在劃位的功能的處理上,我們不使用表單跳頁的方式,而是使用js來控制畫面區塊的切換,這樣就能保留表單的選擇狀態,回上一步時只要切換區塊即可。
  2. 我們也同時使用ajax的方式把選單的內容傳送到後端去產生一份劃位的頁面,並放在#booking區塊中
    ./front/order.php
    1
    2
    3
    4
    5
    <div class="ct">
    <!--點擊選單的確定時,讓兩個div的顯示狀態切換,同時也向後端取得劃位畫面-->
    <button onclick="booking()">確定</button>
    <button>重置</button>
    </div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function booking(){
//取得各個下拉選單的資料,並設定進order物件中
let order={movie_id:$("#movie").val(),
date:$("#date").val(),
session:$("#session").val()}

//將訂票資訊傳至後端./api/booking.php,並取回劃位頁面html內容
$.get("./api/booking.php",order,(booking)=>{

//將劃位頁面的html放至#booking區塊中
$("#booking").html(booking)

//隱藏訂票選單,顯示劃位頁面
$('#select').hide();
$('#booking').show()
})
}

劃位頁面製作

  1. 劃位頁面的產生及劃位行為應該是本題組最複雜的一部份了,這邊要注意的細節比較多,同時也有很多的技巧用來簡化程式碼的撰寫。

  2. 接著我們建立劃位頁面的架構,並建立必要的class name
    ./api/booking.php

    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
    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>
  3. 建立劃位頁面的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;
    }
  4. 根據前端ajax傳來的資料取得劃位頁面需要的內容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    include_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);
    }
  5. 在座位的迴圈中增加對於已訂座位的判斷,並顯示已訂位圖示及不顯示勾選欄位
    ./api/booking.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    echo "<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'>";
    }
  6. 根據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>
  7. 撰寫訂位行為的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)
    })
  8. 撰寫送出訂單函式

    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}`;
    })
    }
  9. 撰寫後端儲存訂單資料的程式
    ./api/checkout.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    include_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'];
  10. 最後是製作訂單結果頁面,我們在劃位的最後按下訂購時,透過ajax取得訂單編號,同時將頁面導向訂單結果頁面,再利用訂單編號取得訂單資料,來產生訂單結果頁面。
    ./front/result.php

    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
    35
    36
    37
    38
    39
    40
    41
    42
    <?php
    //根據訂單編號取得訂單資料
    $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>
    <?php
    //將座位資料轉成陣列
    $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>