◆ wport | pm_29

業務專屬頁面 Mockup PRD

招募活動引擎、業務專屬頁面

來源 doc/feature/pm_29/business-page-mockup.md

業務專屬頁面 Mockup PRD

功能概述

業務專屬頁面讓業務人員(業務以上權限)建立最多 3 個專屬頁面,展示業務個人資訊和選定的職缺。業務落地頁顯示業務大頭照和說明,而非公司資訊。本文件記錄 Storybook Mockup 的實作細節與業務規則。

頁面結構

1. 後台:業務專屬頁面管理(Admin)

1.1 頁面列表(BusinessPageListTable)

欄位順序(與職缺管理一致):

  • 頁面名稱(可點擊,導向業務落地頁)
  • 點擊(PV)
  • 來訪(可點擊,導向人才庫並自動篩選頁面來源)
  • 應徵(可點擊,導向人才庫並自動篩選頁面來源)
  • 狀態(開關切換)
  • 操作(下拉選單:編輯、QR Code、複製連結、刪除

操作功能

  • 頁面名稱點擊:導向業務落地頁
  • 編輯:開啟編輯表單
  • QR Code:顯示 QR Code(Mock)
  • 複製連結:複製業務頁面 URL
  • 刪除:刪除頁面(需確認)

1.2 頁面編輯表單(BusinessPageEditorForm)

表單欄位

  1. 頁面名稱(必填)

    • 類型:文字輸入
    • 驗證:不可為空
  2. 業務說明(選填)

    • 類型:多行文字輸入(textarea)
    • 最大長度:500 字
    • 顯示字數統計
    • 提示:請輸入業務說明(選填)
  3. 頁面網址(自動生成)(只讀)

    • 類型:只讀輸入框 + 複製按鈕
    • 格式:https://example.com/companies/company_id?business_page={slug}
    • 規則:
      • 系統自動生成流水號(格式:business_page_001, business_page_002, …)
      • 新增時自動產生,編輯時顯示現有 slug
      • 不可編輯
      • 可點擊「複製連結」按鈕複製完整 URL
    • 提示文字:「系統自動生成,無法編輯。頁面將顯示業務資訊 + 職缺列表」
  4. 選擇職缺(至少一個,必填)

    • 類型:多選 checkbox 列表
    • 驗證:至少需選擇一個職缺
    • 僅顯示已發布的職缺(status = 1)
    • 篩選功能:
      • 關鍵字搜尋(職務名稱)
      • 職務類別下拉(全部、工程、設計)
      • 工作性質下拉(全部、全職、兼職、遠端)
      • 地點下拉(全部、台北市、新北市、桃園市、台中市、遠端)

頁面上限

  • 每個業務帳號最多只能建立 3 個頁面
  • 達到上限時,新增按鈕會禁用
  • 表單中會顯示警告訊息

表單驗證規則

  • 頁面名稱:必填
  • 職缺選擇:至少選擇一個(僅顯示已發布職缺)

表單提交

  • 驗證失敗時顯示錯誤訊息,不允許提交
  • 驗證通過後執行 onSubmit callback

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。

使用者流程

新增頁面流程

  1. 點擊「新增頁面」按鈕
  2. 檢查頁面上限:
    • 如果已達上限(3 個),顯示警告並禁用按鈕
    • 如果未達上限,開啟表單
  3. 表單開啟,系統自動生成 slug(顯示在「頁面網址」欄位)
  4. 填寫必填欄位:
    • 頁面名稱
    • 選擇至少一個職缺(可使用篩選功能,僅顯示已發布職缺)
  5. (選填)填寫業務說明
  6. 點擊「儲存」
  7. 表單驗證:
    • 如有錯誤,顯示錯誤訊息
    • 驗證通過後,頁面新增至列表

編輯頁面流程

  1. 點擊頁面列表的「編輯」
  2. 表單開啟,預填現有資料
  3. 頁面網址欄位顯示現有 slug(只讀)
  4. 修改欄位(slug 不可修改)
  5. 點擊「儲存」
  6. 表單驗證通過後,更新頁面資料

刪除頁面流程

  1. 點擊頁面列表的「刪除」
  2. 確認對話框:「確定要刪除「{頁面名稱}」嗎?」
  3. 確認後:
    • 頁面從列表中移除
    • 如果刪除的是當前檢視的頁面,切換到第一個頁面

從頁面管理導向業務落地頁

  1. 在頁面列表中點擊頁面名稱
  2. 切換至「業務頁面落地頁」檢視
  3. 顯示業務大頭照、姓名、說明
  4. 顯示業務選定的職缺列表
  5. 用戶可使用篩選器進一步過濾職缺

從頁面管理導向人才庫

  1. 在頁面列表中點擊「來訪」或「應徵」數字
  2. 切換至「人才庫」檢視
  3. 頁面來源自動選中該頁面
  4. Tab 自動切換至對應的「來訪」或「應徵」

技術實作備註

Storybook Mockup 位置

  • Mockup 組件storybook/src/mockupcomponents/business-page/
    • MockupBusinessPageListTable.vue
    • MockupBusinessPageEditorForm.vue
    • MockupBusinessLandingPage.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.vuevalidateForm() 函數中實作:

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)"
/>

後續實作注意事項

  1. 後端 API 設計

    • 業務頁面 CRUD API
    • Slug 自動生成邏輯(流水號格式)
    • 頁面上限檢查(每個業務最多 3 個)
    • 職缺選擇驗證(僅顯示已發布職缺)
  2. 業務資訊取得

    • 業務大頭照、姓名等資訊需從登入狀態或 API 取得
    • Avatar 組件需處理圖片載入失敗的情況
  3. 人才庫整合

    • 實際人才庫頁面需支援業務頁面來源篩選
    • 從業務頁面管理導向人才庫時,需透過 URL query 或 state 傳遞頁面來源
  4. SEO 設定

    • 業務落地頁需設定 noindex meta tag(因為不需要 SEO)
  5. QR Code 生成

    • 後端需提供 QR Code 生成 API
    • QR Code 內容為業務頁面完整 URL

更新記錄

  • 2026-02-09:初版功能需求

    • 業務專屬頁面功能
    • 每個業務最多 3 個頁面
    • 業務落地頁顯示業務大頭照和說明
    • 業務可選擇特定職缺
    • 頁面名稱可點擊,導向業務落地頁
  • 2026-02-09:新增來源追蹤與顯示功能

    • 活動來源顏色區分(公司活動:藍色,業務頁面:綠色)
    • 業務資料隔離(業務只能看到自己的頁面來源)
    • 人才卡片顯示來源標籤(支援複數標籤)
    • 來源標籤可點擊篩選
    • 多來源統計規則(來訪多歸屬,應徵最後點擊)