iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
自我挑戰組

Laravel 讀碼源系列 第 28

美髮預約系統_users的程式碼-新增/編輯資料內容的畫面

  • 分享至 

  • xImage
  •  

https://laihao.vaserver.com/hairdressingusers

要來講解美髮預約系統_users的程式碼

就是MVC架構

各畫面的程式碼解說

新增的前端畫面程式碼
/home/laihao/public_html/resources/views/hairdressing/users/create.blade.php

新增的前端畫面程式碼

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新增使用者</title>
    <style>
        body { font-family: 'Microsoft JhengHei', sans-serif; background: #f9f3ff; }
        h1 { text-align: center; color: #6a0dad; margin-top: 30px; }
        form { width: 90%; max-width: 500px; margin: 0 auto; background: white;
               padding: 25px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
        label { display: block; margin-top: 15px; margin-bottom: 5px; color: #555; font-weight: bold; }
        input, select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 6px;
                        box-sizing: border-box; font-family: inherit; }
        .btn { display: block; width: 100%; margin-top: 20px; background: #6a0dad; color: white;
               text-align: center; padding: 10px; border-radius: 25px; text-decoration: none;
               border: none; cursor: pointer; font-size: 15px; }
        .btn:hover { background: #530a9e; }
        .back { display: block; text-align: center; margin-top: 15px; color: #6a0dad; }
        .error { color: #d9534f; font-size: 13px; margin-top: 4px; }
    </style>
</head>
<body>
    <h1>✨ 新增使用者</h1>

    <form action="{{ route('hairdressingusers.store') }}" method="POST">
        @csrf

        <label>姓名</label>
        <input type="text" name="name" value="{{ old('name') }}" required>
        @error('name') <div class="error">{{ $message }}</div> @enderror

        <label>Email</label>
        <input type="email" name="email" value="{{ old('email') }}" required>
        @error('email') <div class="error">{{ $message }}</div> @enderror

        <label>密碼</label>
        <input type="password" name="password" required>
        @error('password') <div class="error">{{ $message }}</div> @enderror

        <label>角色</label>
        <select name="role" required>
            <option value="admin" {{ old('role') == 'admin' ? 'selected' : '' }}>管理員</option>
            <option value="receptionist" {{ old('role') == 'receptionist' ? 'selected' : '' }}>櫃台</option>
            <option value="stylist" {{ old('role') == 'stylist' ? 'selected' : '' }}>設計師</option>
        </select>
        @error('role') <div class="error">{{ $message }}</div> @enderror

        <label>狀態</label>
        <select name="status" required>
            <option value="active" {{ old('status') == 'active' ? 'selected' : '' }}>啟用</option>
            <option value="inactive" {{ old('status') == 'inactive' ? 'selected' : '' }}>停用</option>
        </select>
        @error('status') <div class="error">{{ $message }}</div> @enderror

        <button type="submit" class="btn">儲存使用者</button>
    </form>

    <a href="{{ route('hairdressingusers.index') }}" class="back">← 返回使用者列表</a>
</body>
</html>

這是一個 Laravel Blade「新增使用者」頁面。它建立一個表單,讓管理者填寫姓名、Email、密碼、角色與狀態;送出後會呼叫 hairdressingusers.store 路由,由控制器驗證並寫入資料庫。

文件與頁面設定

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新增使用者</title>
  • <!DOCTYPE html>:宣告此頁面採用 HTML5。
  • lang="zh-Hant-TW":告訴瀏覽器、搜尋引擎與輔助工具,頁面語言是台灣繁體中文。
  • charset="UTF-8":確保中文、emoji(例如 )能正確顯示。
  • viewport:讓手機版畫面依裝置寬度縮放,提升 RWD 顯示效果。
  • <title>:瀏覽器分頁顯示「新增使用者」。

CSS 樣式

body {
    font-family: 'Microsoft JhengHei', sans-serif;
    background: #f9f3ff;
}
  • 全頁使用微軟正黑體,若使用者裝置沒有此字體,會改用系統預設無襯線字體。
  • background: #f9f3ff 設定淡紫色背景。
form {
    width: 90%;
    max-width: 500px;
    margin: 0 auto;
    background: white;
    padding: 25px;
    border-radius: 10px;
    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}

這段讓表單呈現置中的白色卡片:

  • width: 90%:在小螢幕保留左右邊距。
  • max-width: 500px:桌機不會無限拉寬。
  • margin: 0 auto:水平置中。
  • paddingborder-radiusbox-shadow:增加內距、圓角與陰影,形成卡片風格。
input, select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 6px;
    box-sizing: border-box;
    font-family: inherit;
}
  • input, select:統一文字輸入框與下拉選單的外觀。
  • width: 100%:欄位填滿表單寬度。
  • box-sizing: border-box:讓 padding 和 border 都算在 100% 寬度內,避免欄位超出表單。
  • font-family: inherit:輸入欄位沿用頁面字體。
.btn { ... }
.btn:hover { background: #530a9e; }
  • .btn:送出按鈕為紫色、白字、全寬、圓角。
  • .btn:hover:滑鼠移到按鈕上時顏色變深,提供互動回饋。
.error {
    color: #d9534f;
    font-size: 13px;
    margin-top: 4px;
}
  • .error:欄位驗證失敗時顯示紅色錯誤訊息。

表單送出設定

<form action="{{ route('hairdressingusers.store') }}" method="POST">
    @csrf
  • action="{{ route('hairdressingusers.store') }}":利用 Laravel 的命名路由產生表單送出網址;該路由通常對應控制器的 store() 方法。
  • method="POST":使用 POST 請求新增資料。
  • @csrf:Laravel Blade 指令,產生 CSRF Token 隱藏欄位,防止跨站請求偽造攻擊。缺少它時,Laravel 通常會回傳 419 Page Expired

對應路由通常類似:

Route::resource('hairdressingusers', HairdressingUserController::class);

其中的 hairdressingusers.store 會對應:

POST /hairdressingusers

並執行控制器中的:

public function store(Request $request)

姓名欄位

<label>姓名</label>
<input type="text" name="name" value="{{ old('name') }}" required>
@error('name') <div class="error">{{ $message }}</div> @enderror
  • name="name":送到控制器後可用 $request->name$request->input('name') 取得。
  • required:瀏覽器端要求必填,但後端仍必須保留 Laravel 的驗證規則。
  • old('name'):若後端驗證失敗並導回上一頁,保留使用者原先輸入的姓名。
  • @error('name'):如果 name 驗證失敗,顯示控制器驗證回傳的錯誤訊息。

Email 欄位

<label>Email</label>
<input type="email" name="email" value="{{ old('email') }}" required>
@error('email') <div class="error">{{ $message }}</div> @enderror
  • type="email":瀏覽器會先進行基本 email 格式檢查。
  • name="email":對應控制器中的 email 驗證規則,例如 required|email|max:150|unique:...
  • old('email'):驗證失敗後保留原本輸入的 Email。

密碼欄位

<label>密碼</label>
<input type="password" name="password" required>
@error('password') <div class="error">{{ $message }}</div> @enderror
  • type="password":輸入字元在畫面上會被遮蔽。
  • 密碼沒有使用 old('password'),這是正確且較安全的做法;驗證失敗後不應把密碼重新帶回頁面。
  • 後端應使用 Hash::make($request->password) 再寫入資料庫,而不是直接儲存使用者輸入的明文密碼。

角色選單

<select name="role" required>
    <option value="admin" {{ old('role') == 'admin' ? 'selected' : '' }}>管理員</option>
    <option value="receptionist" {{ old('role') == 'receptionist' ? 'selected' : '' }}>櫃台</option>
    <option value="stylist" {{ old('role') == 'stylist' ? 'selected' : '' }}>設計師</option>
</select>
  • name="role":送出 adminreceptioniststylist 其中一個英文值。
  • 畫面顯示中文,但資料庫通常儲存英文代碼,方便程式判斷與驗證。
  • 三元運算子:
    old('role') == 'admin' ? 'selected' : ''
    
    代表若前一次選的是 admin,驗證失敗回到表單時就自動選回「管理員」。
  • 後端通常會驗證:
    'role' => 'required|in:admin,receptionist,stylist',
    

狀態選單

<select name="status" required>
    <option value="active" {{ old('status') == 'active' ? 'selected' : '' }}>啟用</option>
    <option value="inactive" {{ old('status') == 'inactive' ? 'selected' : '' }}>停用</option>
</select>
  • active:帳號可正常使用。
  • inactive:帳號被停用。
  • 同樣利用 old('status'),在驗證失敗後保留選擇結果。
  • 對應後端驗證通常是:
    'status' => 'required|in:active,inactive',
    

送出與返回

<button type="submit" class="btn">儲存使用者</button>
  • type="submit":按下後送出整個表單。
  • 資料會經由 POST 傳到 hairdressingusers.store 路由。
<a href="{{ route('hairdressingusers.index') }}" class="back">
    ← 返回使用者列表
</a>
  • 以命名路由產生列表頁網址。
  • 點擊後回到使用者清單,不會提交表單。

整體流程

  1. 使用者進入新增頁面,看到表單。
  2. 填寫姓名、Email、密碼、角色、帳號狀態。
  3. 點擊「儲存使用者」。
  4. 表單用 POST 傳送至 hairdressingusers.store
  5. HairdressingUserController::store() 進行欄位驗證。
  6. 驗證失敗:Laravel 導回此頁,@error 顯示錯誤,old() 保留非敏感輸入內容。
  7. 驗證成功:控制器雜湊密碼、建立使用者資料,然後導回使用者列表頁並顯示成功訊息。

編輯的前端畫面程式碼
/home/laihao/public_html/resources/views/hairdressing/users/edit.blade.php
程式碼

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>編輯使用者</title>
    <style>
        body { font-family: 'Microsoft JhengHei', sans-serif; background: #f9f3ff; }
        h1 { text-align: center; color: #6a0dad; margin-top: 30px; }
        form { width: 90%; max-width: 500px; margin: 0 auto; background: white;
               padding: 25px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
        label { display: block; margin-top: 15px; margin-bottom: 5px; color: #555; font-weight: bold; }
        input, select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 6px;
                        box-sizing: border-box; font-family: inherit; }
        .hint { font-size: 12px; color: #999; margin-top: 4px; }
        .btn { display: block; width: 100%; margin-top: 20px; background: #6a0dad; color: white;
               text-align: center; padding: 10px; border-radius: 25px; text-decoration: none;
               border: none; cursor: pointer; font-size: 15px; }
        .btn:hover { background: #530a9e; }
        .back { display: block; text-align: center; margin-top: 15px; color: #6a0dad; }
        .error { color: #d9534f; font-size: 13px; margin-top: 4px; }
    </style>
</head>
<body>
    <h1>✏️ 編輯使用者</h1>

    <form action="{{ route('hairdressingusers.update', $hairdressinguser->id) }}" method="POST">
        @csrf
        @method('PUT')

        <label>姓名</label>
        <input type="text" name="name" value="{{ old('name', $hairdressinguser->name) }}" required>
        @error('name') <div class="error">{{ $message }}</div> @enderror

        <label>Email</label>
        <input type="email" name="email" value="{{ old('email', $hairdressinguser->email) }}" required>
        @error('email') <div class="error">{{ $message }}</div> @enderror

        <label>密碼</label>
        <input type="password" name="password">
        <div class="hint">留空表示不修改密碼</div>
        @error('password') <div class="error">{{ $message }}</div> @enderror

        <label>角色</label>
        <select name="role" required>
            <option value="admin" {{ old('role', $hairdressinguser->role) == 'admin' ? 'selected' : '' }}>管理員</option>
            <option value="receptionist" {{ old('role', $hairdressinguser->role) == 'receptionist' ? 'selected' : '' }}>櫃台</option>
            <option value="stylist" {{ old('role', $hairdressinguser->role) == 'stylist' ? 'selected' : '' }}>設計師</option>
        </select>
        @error('role') <div class="error">{{ $message }}</div> @enderror

        <label>狀態</label>
        <select name="status" required>
            <option value="active" {{ old('status', $hairdressinguser->status) == 'active' ? 'selected' : '' }}>啟用</option>
            <option value="inactive" {{ old('status', $hairdressinguser->status) == 'inactive' ? 'selected' : '' }}>停用</option>
        </select>
        @error('status') <div class="error">{{ $message }}</div> @enderror

        <button type="submit" class="btn">更新使用者</button>
    </form>

    <a href="{{ route('hairdressingusers.index') }}" class="back">← 返回使用者列表</a>
</body>
</html>

路由明天來寫~然後預計開始另一個網頁的解說


上一篇
美髮預約系統_users的程式碼-顯示出資料內容的畫面
下一篇
美髮預約系統_customers 起手式
系列文
Laravel 讀碼源30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言