Files
hr-position-system/docs/SDD.md
DonaldFang 方士碩 a6af297623 backup: 完成 HR_position_ 表格前綴重命名與欄位對照表整理
變更內容:
- 所有資料表加上 HR_position_ 前綴
- 整理完整欄位顯示名稱與 ID 對照表
- 模組化 JS 檔案 (admin.js, ai.js, csv.js 等)
- 專案結構優化 (docs/, scripts/, tests/ 等)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 12:05:20 +08:00

1148 lines
44 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# HR 基礎資料維護系統 - 軟體設計文件 (SDD)
**文件版本**3.1
**建立日期**2024-12-03
**最後更新**2024-12-08
**文件狀態**Released
---
## 1. 文件概述
### 1.1 目的
本文件為 HR 基礎資料維護系統之軟體設計文件 (Software Design Document),詳細描述系統架構、模組設計、資料結構、介面規格與 AI 整合功能,供開發人員、測試人員及維護人員參考。
### 1.2 範圍
本系統涵蓋以下功能模組:
| 模組 | 功能說明 |
|------|----------|
| 崗位基礎資料 | 崗位主檔維護,含基礎資料與招聘要求 |
| 職務基礎資料 | 職務類別與屬性設定維護 |
| 部門職責 | 部門職責定義、使命願景與 KPI 維護 |
| 崗位描述 | 職責描述、崗位要求與任職條件維護 |
| 崗位清單 | 顯示所有崗位資料,支援查看描述與匯出 |
| 管理者頁面 | 使用者管理與完整崗位資料匯出 |
| 組織階層管理 | 事業體、處級單位、部級單位、崗位的層級關聯管理 |
### 1.3 參考文件
- 用戶需求規格書 (URD)
- 系統功能規格書 (FSD)
- API 設計規範
### 1.4 術語定義
| 術語 | 定義 |
|------|------|
| 崗位 (Position) | 組織架構中的職位單位,具有編號、級別、編制人數等屬性 |
| 職務 (Job Title) | 職務類別分類,如管理職、技術職、業務職等 |
| 部門職責 (DeptFunction) | 部門的職責範圍、使命願景與績效指標定義 |
| 崗位描述 (Job Description) | 詳細描述崗位職責、要求與任職條件的文件 |
| 事業體 (Business Unit) | 組織最高層級,代表獨立經營單位 |
| 處級單位 (Division) | 事業體下的次級組織單位 |
| 部級單位 (Department) | 處級單位下的基層組織單位 |
| AI 自動填充 | 利用大型語言模型自動生成表單欄位內容的功能 |
| 三個錦囊 | AI 智能功能區塊,提供自動補齊、範例模板、驗證檢查 |
| LLM | Large Language Model大型語言模型 |
---
## 2. 系統架構
### 2.1 整體架構圖
```
┌─────────────────────────────────────────────────────────────────────┐
│ 使用者介面層 (UI Layer) │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ 崗位基礎 │ │ 職務基礎 │ │ 部門職責 │ │ 崗位描述 │ │
│ │ 模組 │ │ 模組 │ │ 模組 │ │ 模組 │ │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 三個錦囊 AI 功能區 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 自動補齊 │ │ 範例模板 │ │ 驗證檢查 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ ES6 JavaScript 模組化架構 │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ main.js│ │ ui.js │ │ api.js │ │ai-bags │ │utils.js│ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ 應用服務層 (Application Layer) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ Flask RESTful API │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │Position │ │ Job │ │DeptFunc │ │ LLM │ │Hierarchy│ │ │
│ │ │ API │ │ API │ │ API │ │ API │ │ API │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ LLM 配置模組 (llm_config.py) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Gemini │ │DeepSeek │ │ OpenAI │ │ Ollama │ │ GPT-OSS │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ 資料存取層 (Data Layer) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ In-Memory Database / MySQL │ │
│ │ ┌─────────────────┐ ┌─────────────────────────────────────┐ │ │
│ │ │ positions_db │ │ 組織階層資料 │ │ │
│ │ │ jobs_db │ │ (business_units, divisions, │ │ │
│ │ │ dept_func_db │ │ departments, org_positions) │ │ │
│ │ │ job_desc_db │ │ │ │ │
│ │ └─────────────────┘ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
### 2.2 技術堆疊
| 層級 | 技術選型 | 說明 |
|------|----------|------|
| 前端 | HTML5 + CSS3 + ES6 JavaScript | 模組化架構,使用 import/export |
| 樣式 | CSS Modules + Google Fonts | Noto Sans TC 字型、CSS Variables |
| 後端 | Python Flask | RESTful API 服務 |
| AI 服務 | 多 LLM 支援 | Ollama、Gemini、DeepSeek、OpenAI、GPT-OSS |
| 資料庫 | In-Memory + MySQL | 組織階層資料支援 MySQL 持久化 |
### 2.3 前端模組結構
| 檔案 | 功能說明 |
|------|----------|
| js/main.js | 應用程式入口,初始化與事件綁定 |
| js/ui.js | UI 互動邏輯,表單處理與頁籤切換 |
| js/api.js | API 呼叫封裝,與後端通訊 |
| js/ai-bags.js | 三個錦囊 AI 功能實現 |
| js/utils.js | 工具函數Toast、錯誤處理等 |
| js/config.js | 配置常數API 端點等 |
### 2.4 CSS 模組結構
| 檔案 | 功能說明 |
|------|----------|
| styles/base.css | 基礎樣式、CSS 變數、reset |
| styles/layout.css | 頁面佈局、header、sidebar |
| styles/components.css | 按鈕、表單、卡片、Modal 等元件 |
| styles/modules.css | 各模組特定樣式 |
| styles/responsive.css | 響應式設計樣式 |
### 2.5 部署架構
```
┌─────────────────────────────────────────────────────────────────┐
│ 使用者瀏覽器 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ index.html (前端應用ES6 Modules) │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ js/main.js → ui.js → api.js → ai-bags.js │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌────────────────────────────────────┐
│ Flask Server │ │ LLM API Services │
│ localhost:5000 │ │ ┌──────────┐ ┌──────────┐ │
│ ┌───────────────────┐ │ │ │ Ollama │ │ Gemini │ │
│ │ app.py │ │ │ │localhost │ │ Google │ │
│ │ llm_config.py │ │ │ └──────────┘ └──────────┘ │
│ └───────────────────┘ │ │ ┌──────────┐ ┌──────────┐ │
└─────────────────────────┘ │ │ DeepSeek │ │ OpenAI │ │
│ └──────────┘ └──────────┘ │
└────────────────────────────────────┘
```
---
## 3. 模組設計
### 3.1 崗位基礎資料模組
#### 3.1.1 模組概述
提供崗位主檔的 CRUD 操作,分為「基礎資料」與「招聘要求資料」兩個頁籤。
#### 3.1.2 基礎資料頁籤欄位規格
| 欄位名稱 | 欄位ID | 資料類型 | 必填 | 說明 |
|----------|--------|----------|------|------|
| 崗位編號 | positionCode | String(20) | ✓ | 唯一識別碼格式XXX-NNN |
| 崗位名稱 | positionName | String(100) | ✓ | 崗位中文名稱 |
| 崗位類別 | positionCategory | Enum | | 01/02/03/04 |
| 崗位類別名稱 | positionCategoryName | String(50) | | 自動帶出,唯讀 |
| 崗位性質 | positionNature | Enum | | FT/PT/CT/IN |
| 崗位性質名稱 | positionNatureName | String(50) | | 自動帶出,唯讀 |
| 編制人數 | headcount | Integer | | 0-9999 |
| 崗位級別 | positionLevel | Enum | | L1-L7 |
| 生效日期 | effectiveDate | Date | | 預設 2001-01-01 |
| 崗位描述 | positionDesc | Text | | 多行文字 |
| 崗位備注 | positionRemark | Text | | 多行文字 |
#### 3.1.3 招聘要求資料頁籤欄位規格
| 欄位名稱 | 欄位ID | 資料類型 | 說明 |
|----------|--------|----------|------|
| 最低學歷 | minEducation | Enum | HS/JC/BA/MA/PHD |
| 要求性別 | requiredGender | Enum | 空值=不限, M=男, F=女 |
| 薪酬范圍 | salaryRange | Enum | A/B/C/D/E/N |
| 工作經驗 | workExperience | Enum | 0/1/3/5/10 (年) |
| 最小年齡 | minAge | Integer | 18-65 |
| 最大年齡 | maxAge | Integer | 18-65 |
| 工作性質 | jobType | Enum | FT/PT/CT/DP |
| 招聘職位 | recruitPosition | Enum | ENG/MGR/AST/OP/SAL |
| 職位名稱 | jobTitle | String(100) | |
| 職位描述 | jobDesc | Text | |
| 崗位要求 | positionReq | Text | |
| 職稱要求 | titleReq | Enum | NONE/CERT/LIC |
| 專業要求 | majorReq | String(200) | 多選,逗號分隔 |
| 技能要求 | skillReq | String(200) | |
| 語言要求 | langReq | String(100) | |
| 其他要求 | otherReq | String(200) | |
| 上級崗位編號 | superiorPosition | String(20) | |
| 備注說明 | recruitRemark | Text | |
#### 3.1.4 類別代碼對照表
**崗位類別 (positionCategory)**
| 代碼 | 名稱 |
|------|------|
| 01 | 技術職 |
| 02 | 管理職 |
| 03 | 業務職 |
| 04 | 行政職 |
**崗位性質 (positionNature)**
| 代碼 | 名稱 |
|------|------|
| FT | 全職 |
| PT | 兼職 |
| CT | 約聘 |
| IN | 實習 |
**崗位級別 (positionLevel)**
| 代碼 | 名稱 |
|------|------|
| L1 | 基層員工 |
| L2 | 資深員工 |
| L3 | 主管 |
| L4 | 經理 |
| L5 | 總監 |
| L6 | 副總 |
| L7 | 總經理 |
---
### 3.2 職務基礎資料模組
#### 3.2.1 模組概述
提供職務類別主檔的維護功能,包含職務屬性設定。
#### 3.2.2 欄位規格
| 欄位名稱 | 欄位ID | 資料類型 | 必填 | 說明 |
|----------|--------|----------|------|------|
| 職務類別編號 | jobCategoryCode | Enum | ✓ | MGR/TECH/SALE/ADMIN/RD/PROD |
| 職務類別名稱 | jobCategoryName | String(50) | | 自動帶出,唯讀 |
| 職務編號 | jobCode | String(20) | ✓ | 唯一識別碼 |
| 職務名稱 | jobName | String(100) | ✓ | 職務中文名稱 |
| 職務英文 | jobNameEn | String(100) | | 職務英文名稱 |
| 生效日期 | jobEffectiveDate | Date | | |
| 編制人數 | jobHeadcount | Integer | | 0-9999 |
| 排列順序 | jobSortOrder | Integer | | 顯示排序 |
| 備注說明 | jobRemark | Text | | |
| 職務層級 | jobLevel | String(50) | | 可設為 *保密* |
| 是否有全勤 | hasAttendanceBonus | Boolean | | Toggle 開關 |
| 是否住房補貼 | hasHousingAllowance | Boolean | | Toggle 開關 |
#### 3.2.3 職務類別代碼對照表
| 代碼 | 名稱 |
|------|------|
| MGR | 管理職 |
| TECH | 技術職 |
| SALE | 業務職 |
| ADMIN | 行政職 |
| RD | 研發職 |
| PROD | 生產職 |
---
### 3.3 部門職責模組
#### 3.3.1 模組概述
提供部門職責定義維護功能,包含部門使命願景、核心職責與績效指標設定。
#### 3.3.2 欄位規格
| 欄位名稱 | 欄位ID | 資料類型 | 必填 | 說明 |
|----------|--------|----------|------|------|
| 職責編號 | df_code | String(20) | ✓ | 格式 DF-001 |
| 職責名稱 | df_name | String(100) | ✓ | |
| 事業體 | df_businessUnit | Enum | ✓ | SBU/MBU/TBU |
| 處級單位 | df_division | Enum | ✓ | 聯動選項 |
| 部級單位 | df_department | Enum | ✓ | 聯動選項 |
| 課級單位 | df_section | String(50) | | |
| 對應崗位 | df_posTitle | Enum | ✓ | 關聯 Position |
| 崗位級別 | df_posLevel | Enum | | L1-L7 |
| 部門主管職稱 | df_managerTitle | String(100) | | |
| 生效日期 | df_effectiveDate | Date | ✓ | |
| 人數上限 | df_headcountLimit | Integer | | |
| 狀態 | df_status | Enum | | active/inactive |
| 部門使命 | df_mission | Text | | |
| 部門願景 | df_vision | Text | | |
| 核心職責 | df_coreFunc | Text | ✓ | |
| KPIs | df_kpis | Text | | 績效指標 |
| 協作部門 | df_collab | Text | | |
| 備注 | df_remark | Text | | |
#### 3.3.3 狀態代碼對照表
| 代碼 | 名稱 |
|------|------|
| active | 生效中 |
| inactive | 已停用 |
---
### 3.4 崗位描述模組
#### 3.4.1 模組概述
提供完整的崗位描述書 (Job Description) 維護功能,包含崗位基本信息、職責描述與崗位要求三大區塊。
#### 3.4.2 頂部區域欄位
| 欄位名稱 | 欄位ID | 資料類型 | 說明 |
|----------|--------|----------|------|
| 工號 | jd_empNo | String(20) | 員工編號 |
| 姓名 | jd_empName | String(50) | 自動帶出,唯讀 |
| 崗位代碼 | jd_positionCode | String(20) | |
| 版本更新日期 | jd_versionDate | Date | |
#### 3.4.3 崗位基本信息區塊
| 欄位名稱 | 欄位ID | 資料類型 | 說明 |
|----------|--------|----------|------|
| 崗位名稱 | jd_positionName | String(100) | |
| 所屬部門 | jd_department | String(100) | |
| 崗位生效日期 | jd_positionEffectiveDate | Date | |
| 直接領導職務 | jd_directSupervisor | String(100) | |
| 崗位職等&職務 | jd_positionGradeJob | String(100) | 選擇按鈕 |
| 匯報對象職務 | jd_reportTo | String(100) | 選擇按鈕 |
| 直接下級 | jd_directReports | String(200) | 格式:職位 x 人數 |
| 任職地點 | jd_workLocation | Enum | HQ/TPE/TYC/KHH/SH/SZ |
| 員工屬性 | jd_empAttribute | Enum | FT/CT/PT/IN/DP |
#### 3.4.4 職責描述區塊
| 欄位名稱 | 欄位ID | 資料類型 | 說明 |
|----------|--------|----------|------|
| 崗位設置目的 | jd_positionPurpose | String(500) | 單行文字 |
| 主要崗位職責 | jd_mainResponsibilities | Text | 編號格式 1、2、3、... |
#### 3.4.5 崗位要求區塊
| 欄位名稱 | 欄位ID | 資料類型 | 說明 |
|----------|--------|----------|------|
| 教育程度 | jd_education | String(200) | |
| 基本技能 | jd_basicSkills | Text | |
| 專業知識 | jd_professionalKnowledge | Text | |
| 工作經驗 | jd_workExperienceReq | Text | |
| 其他 | jd_otherRequirements | Text | |
#### 3.4.6 任職地點代碼對照表
| 代碼 | 名稱 |
|------|------|
| HQ | 總部 |
| TPE | 台北辦公室 |
| TYC | 桃園廠區 |
| KHH | 高雄廠區 |
| SH | 上海辦公室 |
| SZ | 深圳辦公室 |
#### 3.4.7 員工屬性代碼對照表
| 代碼 | 名稱 |
|------|------|
| FT | 正式員工 |
| CT | 約聘人員 |
| PT | 兼職人員 |
| IN | 實習生 |
| DP | 派遣人員 |
---
## 4. API 設計
### 4.1 API 端點總覽
#### 4.1.1 崗位資料 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/positions` | 獲取所有崗位(支援分頁、搜尋) |
| GET | `/api/positions/{id}` | 獲取單一崗位 |
| POST | `/api/positions` | 新增崗位 |
| PUT | `/api/positions/{id}` | 更新崗位 |
| DELETE | `/api/positions/{id}` | 刪除崗位 |
| POST | `/api/positions/{id}/change-code` | 更改崗位編號 |
#### 4.1.2 職務資料 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/jobs` | 獲取所有職務(支援分頁、搜尋、類別篩選) |
| GET | `/api/jobs/{id}` | 獲取單一職務 |
| POST | `/api/jobs` | 新增職務 |
| PUT | `/api/jobs/{id}` | 更新職務 |
| DELETE | `/api/jobs/{id}` | 刪除職務 |
| POST | `/api/jobs/{id}/change-code` | 更改職務編號 |
#### 4.1.3 崗位描述 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/position-descriptions` | 獲取所有崗位描述 |
| GET | `/api/position-descriptions/{position_code}` | 獲取單一崗位描述 |
| POST | `/api/position-descriptions` | 新增或更新崗位描述 |
| PUT | `/api/position-descriptions/{position_code}` | 更新崗位描述 |
| DELETE | `/api/position-descriptions/{position_code}` | 刪除崗位描述 |
#### 4.1.4 崗位清單 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/position-list` | 獲取崗位清單(支援分頁、搜尋) |
| GET | `/api/position-list/export` | 匯出完整崗位清單為 CSV |
#### 4.1.5 CSV 匯入匯出 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/positions/csv-template` | 下載崗位資料 CSV 範本 |
| POST | `/api/positions/import-csv` | 批次匯入崗位資料 |
| GET | `/api/jobs/csv-template` | 下載職務資料 CSV 範本 |
| POST | `/api/jobs/import-csv` | 批次匯入職務資料 |
#### 4.1.6 參照資料 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/reference/categories` | 崗位類別選項 |
| GET | `/api/reference/job-categories` | 職務類別選項 |
| GET | `/api/reference/natures` | 崗位性質選項 |
| GET | `/api/reference/education` | 學歷選項 |
| GET | `/api/reference/majors` | 專業選項 |
#### 4.1.7 組織階層 API
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/api/hierarchy/business-units` | 獲取所有事業體 |
| GET | `/api/hierarchy/divisions` | 獲取處級單位(可按事業體篩選) |
| GET | `/api/hierarchy/departments` | 獲取部級單位(可按處級單位篩選) |
| GET | `/api/hierarchy/positions` | 獲取崗位名稱(可按部級單位篩選) |
| GET | `/api/hierarchy/full` | 獲取完整階層資料(支援分頁) |
| GET | `/api/hierarchy/cascade` | 獲取級聯選擇資料 |
| GET | `/api/hierarchy/stats` | 獲取組織統計資訊 |
### 4.2 API 請求/回應範例
#### 4.2.1 新增崗位
**Request**
```http
POST /api/positions
Content-Type: application/json
{
"basicInfo": {
"positionCode": "ENG-001",
"positionName": "資深軟體工程師",
"positionCategory": "01",
"positionNature": "FT",
"headcount": "5",
"positionLevel": "L3",
"effectiveDate": "2024-01-01",
"positionDesc": "負責系統架構設計與核心模組開發"
},
"recruitInfo": {
"minEducation": "BA",
"salaryRange": "D",
"workExperience": "5",
"skillReq": "Python, JavaScript, SQL"
}
}
```
**Response (201 Created)**
```json
{
"success": true,
"message": "崗位資料新增成功",
"data": {
"id": "ENG-001",
"basicInfo": { ... },
"recruitInfo": { ... },
"createdAt": "2024-12-03T10:30:00",
"updatedAt": "2024-12-03T10:30:00"
}
}
```
#### 4.2.2 查詢崗位列表
**Request**
```http
GET /api/positions?page=1&size=20&search=工程師
```
**Response (200 OK)**
```json
{
"success": true,
"data": [
{
"id": "ENG-001",
"basicInfo": { ... },
"recruitInfo": { ... }
}
],
"pagination": {
"page": 1,
"size": 20,
"total": 1,
"totalPages": 1
}
}
```
### 4.3 錯誤處理
| HTTP 狀態碼 | 錯誤類型 | 說明 |
|-------------|----------|------|
| 400 | Bad Request | 請求參數錯誤或缺少必填欄位 |
| 404 | Not Found | 找不到指定資源 |
| 409 | Conflict | 資源衝突(如編號已存在) |
| 500 | Internal Server Error | 伺服器內部錯誤 |
**錯誤回應格式**
```json
{
"success": false,
"error": "錯誤訊息描述"
}
```
---
## 5. AI 智能功能設計
### 5.1 功能概述
系統整合多種 LLM API提供「三個錦囊」智能功能區塊
| 錦囊 | 功能 | 說明 |
|------|------|------|
| 自動補齊 | AI 自動填充 | 根據已填內容智能生成其餘欄位 |
| 範例模板 | 範例資料生成 | 提供符合行業標準的範例資料 |
| 驗證檢查 | 資料驗證建議 | 檢查資料完整性與合理性 |
### 5.2 支援的 LLM 服務
| 服務 | 配置鍵 | 預設模型 | 說明 |
|------|--------|----------|------|
| Ollama | OLLAMA_API_KEY | qwen2.5:3b | 本地部署,無需 API 費用 |
| Gemini | GEMINI_API_KEY | gemini-pro | Google AI 服務 |
| DeepSeek | DEEPSEEK_API_KEY | deepseek-chat | 中文優化模型 |
| OpenAI | OPENAI_API_KEY | gpt-3.5-turbo | OpenAI 官方服務 |
| GPT-OSS | GPTOSS_API_KEY | - | 開源替代服務 |
### 5.3 三個錦囊 UI 設計
```
┌─────────────────────────────────────────────────────┐
│ 三個錦囊 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 自動補齊 │ │ 範例模板 │ │ 驗證檢查 │ │
│ │ AI │ │ Template │ │ Validate │ │
│ │ (Edit) │ │ (Edit) │ │ (Edit) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
```
### 5.4 Prompt 編輯功能
每個錦囊支援 Prompt 編輯,用戶可自訂 AI 生成邏輯:
- 標題:錦囊顯示名稱
- 副標題:功能簡述
- Prompt發送給 LLM 的指令內容
- 儲存至 LocalStorage持久化設定
### 5.5 填充邏輯
```
┌─────────────────────────────────────────────────────────┐
│ AI 填充流程 │
├─────────────────────────────────────────────────────────┤
│ 1. 用戶點擊「I'm feeling lucky」按鈕 │
│ │ │
│ ▼ │
│ 2. 檢查表單欄位狀態 │
│ ├── 收集已填寫欄位 (作為上下文) │
│ └── 識別空白欄位 (待填充目標) │
│ │ │
│ ▼ │
│ 3. 若無空白欄位 → 顯示「所有欄位都已填寫完成!」 │
│ 若有空白欄位 → 繼續 │
│ │ │
│ ▼ │
│ 4. 組裝 Prompt │
│ ├── 包含已填寫資料作為參考 │
│ ├── 指定只生成空白欄位 │
│ └── 要求返回 JSON 格式 │
│ │ │
│ ▼ │
│ 5. 呼叫 Claude API (claude-sonnet-4-20250514) │
│ │ │
│ ▼ │
│ 6. 解析回應並填充空白欄位 │
│ └── 已有內容的欄位保持不變 │
│ │ │
│ ▼ │
│ 7. 顯示「✨ AI 已補充 N 個欄位!」 │
└─────────────────────────────────────────────────────────┘
```
### 5.6 核心函數
#### 5.6.1 fillIfEmpty
```javascript
/**
* 只在欄位為空時填入值
* @param {string} elementId - DOM 元素 ID
* @param {string} value - 要填入的值
* @returns {boolean} - 是否有填入值
*/
function fillIfEmpty(elementId, value) {
const el = document.getElementById(elementId);
if (el && !el.value.trim() && value) {
el.value = value;
return true;
}
return false;
}
```
#### 5.6.2 getEmptyFields
```javascript
/**
* 獲取空白欄位列表
* @param {string[]} fieldIds - 欄位 ID 陣列
* @returns {string[]} - 空白欄位 ID 陣列
*/
function getEmptyFields(fieldIds) {
return fieldIds.filter(id => !getFieldValue(id));
}
```
### 5.7 API 呼叫規格
**本地 Flask API Endpoint**
```
POST http://localhost:5000/api/llm/generate
```
**Request Body**
```json
{
"api": "ollama",
"model": "qwen2.5:3b",
"prompt": "Prompt 內容...",
"max_tokens": 2000
}
```
### 5.8 Prompt 設計範例
```
請為HR崗位管理系統生成崗位基礎資料。請用繁體中文回覆。
已填寫的資料(請參考這些內容來生成相關的資料):
{
"positionName": "資深前端工程師",
"positionLevel": "L4"
}
請「只生成」以下這些尚未填寫的欄位positionCode, positionCategory, positionNature, headcount, positionDesc
欄位說明:
- positionCode: 崗位編號(格式如 ENG-001
- positionCategory: 崗位類別代碼01=技術職, 02=管理職...
...
請直接返回JSON格式只包含需要生成的欄位
{
"positionCode": "...",
"positionCategory": "...",
...
}
```
---
## 6. 使用者介面設計
### 6.1 色彩規範
| 變數名稱 | 色碼 | 用途 |
|----------|------|------|
| --primary | #1a5276 | 主色(崗位模組) |
| --primary-light | #2980b9 | 主色亮色 |
| --primary-dark | #0e3a53 | 主色暗色 |
| --accent | #e67e22 | 強調色(職務模組) |
| --green | #27ae60 | 綠色(崗位描述模組) |
| --success | #27ae60 | 成功狀態 |
| --warning | #f39c12 | 警告狀態 |
| --danger | #e74c3c | 錯誤/必填標示 |
### 6.2 模組主題色
| 模組 | Header 背景 | 按鈕樣式 |
|------|-------------|----------|
| 崗位基礎資料 | 藍色漸層 | primary |
| 職務基礎資料 | 橘色漸層 | accent |
| 崗位描述 | 綠色漸層 | green |
### 6.3 元件規格
#### 6.3.1 輸入框
```css
input, select, textarea {
padding: 10px 14px;
border: 1.5px solid var(--border);
border-radius: 6px;
font-size: 0.9rem;
}
```
#### 6.3.2 按鈕
| 類型 | Class | 用途 |
|------|-------|------|
| 主要按鈕 | .btn-primary | 保存操作 |
| 次要按鈕 | .btn-secondary | 保存並新增 |
| 取消按鈕 | .btn-cancel | 取消操作 |
| AI 按鈕 | .ai-generate-btn | AI 自動填充 |
#### 6.3.3 Toggle 開關
```css
.toggle-switch {
width: 52px;
height: 28px;
}
```
### 6.4 響應式斷點
| 斷點 | 寬度 | 佈局調整 |
|------|------|----------|
| Desktop | > 768px | 雙欄表單佈局 |
| Mobile | ≤ 768px | 單欄表單佈局 |
---
## 7. 資料結構
### 7.1 崗位資料 (Position)
```typescript
interface Position {
id: string; // 崗位編號 (PK)
basicInfo: {
positionCode: string; // 崗位編號
positionName: string; // 崗位名稱
positionCategory: string; // 崗位類別
positionCategoryName: string;// 崗位類別名稱
positionNature: string; // 崗位性質
positionNatureName: string; // 崗位性質名稱
headcount: string; // 編制人數
positionLevel: string; // 崗位級別
effectiveDate: string; // 生效日期
positionDesc: string; // 崗位描述
positionRemark: string; // 崗位備注
};
recruitInfo: {
minEducation: string; // 最低學歷
requiredGender: string; // 要求性別
salaryRange: string; // 薪酬范圍
workExperience: string; // 工作經驗
minAge: string; // 最小年齡
maxAge: string; // 最大年齡
jobType: string; // 工作性質
recruitPosition: string; // 招聘職位
jobTitle: string; // 職位名稱
jobDesc: string; // 職位描述
positionReq: string; // 崗位要求
titleReq: string; // 職稱要求
majorReq: string; // 專業要求
skillReq: string; // 技能要求
langReq: string; // 語言要求
otherReq: string; // 其他要求
superiorPosition: string; // 上級崗位編號
recruitRemark: string; // 備注說明
};
createdAt: string; // 建立時間
updatedAt: string; // 更新時間
}
```
### 7.2 職務資料 (Job)
```typescript
interface Job {
id: string; // 職務編號 (PK)
jobCategoryCode: string; // 職務類別編號
jobCategoryName: string; // 職務類別名稱
jobCode: string; // 職務編號
jobName: string; // 職務名稱
jobNameEn: string; // 職務英文名稱
jobEffectiveDate: string; // 生效日期
jobHeadcount: number; // 編制人數
jobSortOrder: number; // 排列順序
jobRemark: string; // 備注說明
jobLevel: string; // 職務層級
hasAttendanceBonus: boolean; // 是否有全勤
hasHousingAllowance: boolean; // 是否住房補貼
createdAt: string; // 建立時間
updatedAt: string; // 更新時間
}
```
### 7.3 崗位描述資料 (PositionDescription)
```typescript
interface PositionDescription {
id: string; // 崗位編號 (PK)
positionCode: string; // 崗位編號
positionName: string; // 崗位名稱
effectiveDate: string; // 生效日期
jobDuties: string; // 工作職責
requiredSkills: string; // 所需技能
workEnvironment: string; // 工作環境
careerPath: string; // 職涯發展路徑
createdAt: string; // 建立時間
updatedAt: string; // 更新時間
}
```
### 7.4 崗位清單資料 (PositionListItem)
```typescript
interface PositionListItem {
positionCode: string; // 崗位編號
positionName: string; // 崗位名稱
positionCategory: string; // 崗位類別
positionNature: string; // 崗位性質
headcount: string; // 編制人數
positionLevel: string; // 崗位等級
effectiveDate: string; // 生效日期
minEducation: string; // 最低學歷
salaryRange: string; // 薪資範圍
hasDescription: boolean; // 是否有描述
jobDuties: string; // 工作職責
requiredSkills: string; // 所需技能
workEnvironment: string; // 工作環境
createdAt: string; // 建立時間
updatedAt: string; // 更新時間
}
```
### 7.5 組織階層資料結構
#### 7.5.1 事業體 (BusinessUnit)
```typescript
interface BusinessUnit {
id: number; // 主鍵
business_code: string; // 事業體代碼 (BU001, BU002...)
business_name: string; // 事業體名稱
sort_order: number; // 排序
is_active: boolean; // 是否啟用
remark: string; // 備註
created_at: string; // 建立時間
updated_at: string; // 更新時間
}
```
#### 7.5.2 處級單位 (Division)
```typescript
interface Division {
id: number; // 主鍵
division_code: string; // 處級單位代碼 (DIV001, DIV002...)
division_name: string; // 處級單位名稱
business_id: number; // 所屬事業體ID (FK)
sort_order: number; // 排序
is_active: boolean; // 是否啟用
remark: string; // 備註
created_at: string; // 建立時間
updated_at: string; // 更新時間
}
```
#### 7.5.3 部級單位 (Department)
```typescript
interface Department {
id: number; // 主鍵
department_code: string; // 部級單位代碼 (DEPT001, DEPT002...)
department_name: string; // 部級單位名稱
division_id: number; // 所屬處級單位ID (FK)
sort_order: number; // 排序
is_active: boolean; // 是否啟用
remark: string; // 備註
created_at: string; // 建立時間
updated_at: string; // 更新時間
}
```
#### 7.5.4 組織崗位關聯 (OrganizationPosition)
```typescript
interface OrganizationPosition {
id: number; // 主鍵
business_id: number; // 事業體ID (FK)
division_id: number; // 處級單位ID (FK)
department_id: number; // 部級單位ID (FK)
position_title: string; // 崗位名稱
sort_order: number; // 排序
is_active: boolean; // 是否啟用
created_at: string; // 建立時間
updated_at: string; // 更新時間
}
```
#### 7.5.5 組織階層關係圖
```
事業體 (business_units)
├── 岡山製造事業體
│ ├── 生產處 (divisions)
│ │ ├── 生產部 (departments)
│ │ │ ├── 經副理 (organization_positions)
│ │ │ ├── 課長
│ │ │ ├── 組長
│ │ │ └── 班長
│ │ └── 生產企劃部
│ │ ├── 經副理
│ │ └── 專員
│ ├── 封裝工程處
│ └── ...
├── 產品事業體
│ ├── 先進產品事業處
│ └── 成熟產品事業處
└── ...(共 15 個事業體)
```
#### 7.5.6 資料統計
| 層級 | 資料筆數 |
|------|----------|
| 事業體 | 15 筆 |
| 處級單位 | ~45 筆 |
| 部級單位 | ~70 筆 |
| 組織崗位關聯 | ~350 筆(去重後) |
---
## 8. 快捷鍵設計
| 快捷鍵 | 功能 | 適用範圍 |
|--------|------|----------|
| `Ctrl + S` | 保存并退出 | 所有模組 |
| `Ctrl + N` | 保存并新增 | 所有模組 |
---
## 9. 檔案結構
```
hr_position_form/
├── index.html # 前端應用主檔
├── app.py # Flask 後端 API
├── llm_config.py # LLM API 配置模組
├── database_schema.sql # MySQL 資料庫結構定義
├── init_database.py # 資料庫初始化腳本
├── import_hierarchy_data.py # 組織階層資料匯入腳本
├── hierarchical_data.js # 組織階層原始資料
├── requirements.txt # Python 依賴套件
├── .env # 環境變數配置 (API Keys)
├── README.md # 使用說明文件
├── SDD.md # 軟體設計文件
├── TDD.md # 測試設計文件
├── js/ # JavaScript 模組
│ ├── main.js # 應用程式入口
│ ├── ui.js # UI 互動邏輯
│ ├── api.js # API 呼叫封裝
│ ├── ai-bags.js # 三個錦囊功能
│ ├── utils.js # 工具函數
│ └── config.js # 配置常數
├── styles/ # CSS 樣式模組
│ ├── base.css # 基礎樣式
│ ├── layout.css # 頁面佈局
│ ├── components.css # UI 元件
│ ├── modules.css # 模組樣式
│ └── responsive.css # 響應式設計
└── data/ # 資料檔案
├── positions.csv # 崗位資料範本
└── jobs.csv # 職務資料範本
```
---
## 10. 未來擴展建議
### 10.1 資料庫整合
將 In-Memory 儲存替換為正式資料庫:
```python
# 建議使用 SQLAlchemy ORM
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:pass@host/db'
db = SQLAlchemy(app)
```
### 10.2 權限控制整合
```python
# 建議整合 Azure AD
from flask_azure_oauth import AzureOAuth
azure_oauth = AzureOAuth(app)
@app.route('/api/positions', methods=['POST'])
@azure_oauth.require_auth
def create_position():
...
```
### 10.3 審計日誌
```python
# 記錄所有資料變更
def log_audit(action, entity_type, entity_id, old_data, new_data, user_id):
audit_log = {
'action': action, # CREATE/UPDATE/DELETE
'entity_type': entity_type,
'entity_id': entity_id,
'old_data': old_data,
'new_data': new_data,
'user_id': user_id,
'timestamp': datetime.now().isoformat()
}
# 儲存至審計日誌表
```
### 10.4 多語言支援
```javascript
// i18n 國際化
const i18n = {
'zh-TW': {
'position.code': '崗位編號',
'position.name': '崗位名稱',
...
},
'en-US': {
'position.code': 'Position Code',
'position.name': 'Position Name',
...
}
};
```
---
## 11. 版本歷史
| 版本 | 日期 | 作者 | 變更說明 |
|------|------|------|----------|
| 1.0 | 2024-12-03 | System | 初始版本,包含三大模組設計與 AI 功能 |
| 2.0 | 2024-12-04 | System | 新增 MySQL 資料庫整合、多 LLM API 支援、全局錯誤處理、Gitea 版本控制 |
| 2.1 | 2024-12-04 | System | 新增崗位描述保存功能、崗位清單模組、管理者頁面匯出功能、CSV 批次匯入 |
| 3.0 | 2024-12-06 | System | 新增部門職責模組、三個錦囊 AI 功能、ES6 模組化架構、改進 JSON 解析錯誤處理 |
| 3.1 | 2024-12-08 | System | 新增組織階層管理模組,包含事業體、處級單位、部級單位、崗位的四層架構;新增 7 個組織階層 API 端點;更新資料庫結構支援組織階層資料 |
---
## 12. 附錄
### 附錄 AJSON 資料預覽格式
系統提供即時 JSON 預覽功能,格式如下:
```json
{
"module": "崗位基礎資料",
"basicInfo": {
"positionCode": "ENG-001",
"positionName": "資深軟體工程師",
"positionCategory": "01",
"positionCategoryName": "技術職",
"positionNature": "FT",
"positionNatureName": "全職",
"headcount": "5",
"positionLevel": "L3"
},
"recruitInfo": {
"minEducation": "BA",
"salaryRange": "D",
"workExperience": "5"
}
}
```
### 附錄 BUI 截圖參考
(請參考系統實際畫面)
---
**文件結束**