業務專屬頁面 Mockup PRD
功能概述
業務專屬頁面讓業務人員(業務以上權限)建立最多 3 個專屬頁面,展示業務個人資訊和選定的職缺。業務落地頁顯示業務大頭照和說明,而非公司資訊。本文件記錄 Storybook Mockup 的實作細節與業務規則。
頁面結構
1. 後台:業務專屬頁面管理(Admin)
1.1 頁面列表(BusinessPageListTable)
欄位順序(與職缺管理一致):
- 頁面名稱(可點擊,導向業務落地頁)
- 點擊(PV)
- 來訪(可點擊,導向人才庫並自動篩選頁面來源)
- 應徵(可點擊,導向人才庫並自動篩選頁面來源)
- 狀態(開關切換)
- 操作(下拉選單:編輯、QR Code、複製連結、刪除)
操作功能:
- 頁面名稱點擊:導向業務落地頁
- 編輯:開啟編輯表單
- QR Code:顯示 QR Code(Mock)
- 複製連結:複製業務頁面 URL
- 刪除:刪除頁面(需確認)
1.2 頁面編輯表單(BusinessPageEditorForm)
表單欄位:
-
頁面名稱(必填)
- 類型:文字輸入
- 驗證:不可為空
-
業務說明(選填)
- 類型:多行文字輸入(textarea)
- 最大長度:500 字
- 顯示字數統計
- 提示:請輸入業務說明(選填)
-
頁面網址(自動生成)(只讀)
- 類型:只讀輸入框 + 複製按鈕
- 格式:
https://example.com/companies/company_id?business_page={slug} - 規則:
- 系統自動生成流水號(格式:
business_page_001,business_page_002, …) - 新增時自動產生,編輯時顯示現有 slug
- 不可編輯
- 可點擊「複製連結」按鈕複製完整 URL
- 系統自動生成流水號(格式:
- 提示文字:「系統自動生成,無法編輯。頁面將顯示業務資訊 + 職缺列表」
-
選擇職缺(至少一個,必填)
- 類型:多選 checkbox 列表
- 驗證:至少需選擇一個職缺
- 僅顯示已發布的職缺(status = 1)
- 篩選功能:
- 關鍵字搜尋(職務名稱)
- 職務類別下拉(全部、工程、設計)
- 工作性質下拉(全部、全職、兼職、遠端)
- 地點下拉(全部、台北市、新北市、桃園市、台中市、遠端)
頁面上限:
- 每個業務帳號最多只能建立 3 個頁面
- 達到上限時,新增按鈕會禁用
- 表單中會顯示警告訊息
表單驗證規則:
- 頁面名稱:必填
- 職缺選擇:至少選擇一個(僅顯示已發布職缺)
表單提交:
- 驗證失敗時顯示錯誤訊息,不允許提交
- 驗證通過後執行
onSubmitcallback
2. 前台:業務落地頁(Candidate Landing)
設計策略:顯示業務個人資訊,而非公司資訊
版面結構:
- 業務 Header:
- 業務大頭照(使用 NAvatar 組件,120x120px,圓形)
- 業務姓名
- 業務說明(如果有)
- 職缺機會區塊:
- 職缺篩選列(工作性質、職務類別、地點)
- 職缺卡片列表(僅顯示業務選定的職缺)
職缺顯示規則:
- 只顯示業務在編輯表單中選定的職缺(
job_ids) - 用戶可使用篩選器進一步過濾已選定的職缺
- 如果篩選後沒有符合條件的職缺,顯示「暫無符合條件的職缺」
Avatar 組件:
- 使用 Naive UI 的
NAvatar組件 - 設定
size="120"、round(圓形) - 設定
fallback-src作為備用圖片(顯示姓名首字) - 避免圖片破圖問題
3. 人才庫整合
業務頁面來源篩選:
- 人才庫的「活動來源」下拉選單包含:
- 公司活動(所有業務可見,藍色標示)
- 業務頁面(只顯示當前業務自己的頁面,綠色標示)
- 從業務頁面管理點擊「來訪」或「應徵」時,會自動帶入該頁面來源篩選
資料隔離規則:
- 業務只能看到自己建立的業務頁面來源
- 公司層級的招募活動所有業務都可見
- 人才卡片上的來源標籤會自動過濾,只顯示當前業務能看到的來源
來源顯示與互動:
- 人才卡片上會顯示來源標籤(複數)
- 標籤顏色區分:
- 公司活動:藍色(#e3f2fd 背景,#1976d2 文字)
- 業務頁面:綠色(#e8f5e9 背景,#388e3c 文字)
- 標籤可點擊:點擊標籤等同於在左側 filter 選擇該活動來源
- 下拉選單選項也有對應的顏色區分
多來源支援:
- 如果求職者訪問了多個業務頁面(例如:A1、A2、A3),會顯示多個標籤
- 篩選時,選擇任一來源(A1、A2 或 A3)都能找到該求職者
- 統計邏輯:
- 來訪統計:所有訪問過的頁面都計入(A1、A2、A3 的來訪都 +1)
- 應徵統計:只有最後點擊的頁面計入(只有 A3 的應徵 +1)
業務規則
1. 頁面上限規則
- 每個業務帳號最多只能建立 3 個頁面
- 達到上限時:
- 「新增頁面」按鈕會禁用
- 表單中會顯示警告訊息:「⚠️ 已達頁面上限(3 個),請刪除現有頁面後再新增」
- 刪除頁面後,可以繼續新增
2. URL Slug 生成規則
- 自動生成:系統自動產生流水號格式的 slug(
business_page_001,business_page_002, …) - 不可編輯:slug 一旦生成後不可修改
- 唯一性:每個頁面的 slug 都是唯一的
- 顯示與複製:表單中顯示完整 URL,提供「複製連結」按鈕
URL 格式:
https://example.com/companies/company_id?business_page={slug}
3. 必填欄位驗證
以下欄位為必填:
- 頁面名稱:不可為空
- 職缺選擇:至少需選擇一個職缺(僅顯示已發布職缺)
以下欄位為選填:
- 業務說明:可選填,最多 500 字
表單提交前會進行驗證,任一必填欄位未填寫時,顯示錯誤訊息並阻止提交。
4. 職缺選擇規則
- 僅顯示已發布的職缺(status = 1)
- 至少需選擇一個職缺
- 業務可以透過篩選器(關鍵字、職務類別、工作性質、地點)來尋找職缺
- 選定的職缺會顯示在業務落地頁
5. 業務落地頁顯示規則
- 顯示業務個人資訊:
- 業務大頭照(使用 NAvatar,避免破圖)
- 業務姓名
- 業務說明(如果有)
- 顯示選定的職缺:
- 只顯示業務在編輯表單中選定的職缺
- 用戶可使用篩選器進一步過濾
- 不顯示公司資訊:與公司頁面不同,業務頁面專注於業務個人品牌
Mock 資料結構
MockBusinessPageItem
interface MockBusinessPageItem {
enc_id: string // 頁面 ID(與 slug 相同)
name: string // 頁面名稱(必填)
status: 0 | 1 // 狀態(0: 關閉, 1: 開啟)
pv: number // 點擊數
visitors_count: number // 來訪數(所有訪問過此頁面的人數)
applications_count: number // 應徵數(最後點擊此頁面的應徵人數)
slug: string // URL slug(自動生成,只讀)
description?: string // 業務說明(選填,最多 500 字)
job_ids: string[] // 選定的職缺 ID 列表(至少一個,僅已發布職缺)
business_uid: string // 業務 UID(當前擁有者)
}
MockResumeItem(人才庫記錄)
interface MockSourceItem {
id: string // 來源 ID(活動或業務頁面 ID)
name: string // 來源名稱
type: 'company_campaign' | 'business_page'
business_uid?: string // 如果是業務頁面,記錄業務 UID
}
interface MockResumeItem {
// ... 基本欄位 ...
sources?: MockSourceItem[] // 所有來源(複數,用於顯示標籤)
}
MockBusinessUser
interface MockBusinessUser {
enc_id: string // 業務 UID
name: string // 業務姓名
email: string // 業務 Email
photo_url: string // 業務大頭照 URL
}
Slug 生成邏輯
let businessPageCounter = 1
function generateBusinessPageId(): string {
return `business_page_${String(businessPageCounter++).padStart(3, '0')}`
}
新增頁面時,系統自動呼叫 generateBusinessPageId() 產生新的 slug。
使用者流程
新增頁面流程
- 點擊「新增頁面」按鈕
- 檢查頁面上限:
- 如果已達上限(3 個),顯示警告並禁用按鈕
- 如果未達上限,開啟表單
- 表單開啟,系統自動生成 slug(顯示在「頁面網址」欄位)
- 填寫必填欄位:
- 頁面名稱
- 選擇至少一個職缺(可使用篩選功能,僅顯示已發布職缺)
- (選填)填寫業務說明
- 點擊「儲存」
- 表單驗證:
- 如有錯誤,顯示錯誤訊息
- 驗證通過後,頁面新增至列表
編輯頁面流程
- 點擊頁面列表的「編輯」
- 表單開啟,預填現有資料
- 頁面網址欄位顯示現有 slug(只讀)
- 修改欄位(slug 不可修改)
- 點擊「儲存」
- 表單驗證通過後,更新頁面資料
刪除頁面流程
- 點擊頁面列表的「刪除」
- 確認對話框:「確定要刪除「{頁面名稱}」嗎?」
- 確認後:
- 頁面從列表中移除
- 如果刪除的是當前檢視的頁面,切換到第一個頁面
從頁面管理導向業務落地頁
- 在頁面列表中點擊頁面名稱
- 切換至「業務頁面落地頁」檢視
- 顯示業務大頭照、姓名、說明
- 顯示業務選定的職缺列表
- 用戶可使用篩選器進一步過濾職缺
從頁面管理導向人才庫
- 在頁面列表中點擊「來訪」或「應徵」數字
- 切換至「人才庫」檢視
- 頁面來源自動選中該頁面
- Tab 自動切換至對應的「來訪」或「應徵」
技術實作備註
Storybook Mockup 位置
- Mockup 組件:
storybook/src/mockupcomponents/business-page/MockupBusinessPageListTable.vueMockupBusinessPageEditorForm.vueMockupBusinessLandingPage.vue
- Mock 資料:
storybook/src/mockupcomponents/business-page/mockBusinessPageData.ts
- Demo 頁面:
storybook/src/mockups/business-page-demo.vue - Story 檔案:
storybook/src/stories/mockups/recruitment/BusinessPage.stories.ts
狀態管理
pageList:頁面列表狀態(ref<MockBusinessPageItem[]>)maxPages:最多頁面數(ref<number>,預設 3)currentPageCount:當前頁面數量(computed)candidatePage:當前檢視的頁面(ref<MockBusinessPageItem>)
驗證邏輯
表單驗證在 MockupBusinessPageEditorForm.vue 的 validateForm() 函數中實作:
const validateForm = (): boolean => {
formErrors.value = { name: '', job_ids: '' }
let valid = true
if (!form.value.name.trim()) {
formErrors.value.name = '頁面名稱為必填'
valid = false
}
if (form.value.job_ids.length === 0) {
formErrors.value.job_ids = '至少需選擇一個職缺'
valid = false
}
return valid
}
Avatar 組件使用
<NAvatar
:size="120"
:src="mockBusinessUser.photo_url"
round
:fallback-src="'https://via.placeholder.com/120?text=' + mockBusinessUser.name.charAt(0)"
/>
後續實作注意事項
-
後端 API 設計:
- 業務頁面 CRUD API
- Slug 自動生成邏輯(流水號格式)
- 頁面上限檢查(每個業務最多 3 個)
- 職缺選擇驗證(僅顯示已發布職缺)
-
業務資訊取得:
- 業務大頭照、姓名等資訊需從登入狀態或 API 取得
- Avatar 組件需處理圖片載入失敗的情況
-
人才庫整合:
- 實際人才庫頁面需支援業務頁面來源篩選
- 從業務頁面管理導向人才庫時,需透過 URL query 或 state 傳遞頁面來源
-
SEO 設定:
- 業務落地頁需設定
noindexmeta tag(因為不需要 SEO)
- 業務落地頁需設定
-
QR Code 生成:
- 後端需提供 QR Code 生成 API
- QR Code 內容為業務頁面完整 URL
更新記錄
-
2026-02-09:初版功能需求
- 業務專屬頁面功能
- 每個業務最多 3 個頁面
- 業務落地頁顯示業務大頭照和說明
- 業務可選擇特定職缺
- 頁面名稱可點擊,導向業務落地頁
-
2026-02-09:新增來源追蹤與顯示功能
- 活動來源顏色區分(公司活動:藍色,業務頁面:綠色)
- 業務資料隔離(業務只能看到自己的頁面來源)
- 人才卡片顯示來源標籤(支援複數標籤)
- 來源標籤可點擊篩選
- 多來源統計規則(來訪多歸屬,應徵最後點擊)