This commit is contained in:
beabigegg
2025-09-01 11:17:09 +08:00
parent 8185b609f7
commit 22a231d78c
7 changed files with 1087 additions and 350 deletions

View File

@@ -25,7 +25,16 @@
"Bash(start chrome:*)",
"Bash(taskkill:*)",
"Bash(TASKKILL:*)",
"Bash(wmic process where:*)"
"Bash(wmic process where:*)",
"Bash(\"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe\" --remote-debugging-port=9222 --user-data-dir=\"%TEMP%\\chrome-debug\" http://localhost:3000/todos)",
"Bash(timeout:*)",
"Bash(ping:*)",
"mcp__puppeteer__puppeteer_navigate",
"mcp__puppeteer__puppeteer_screenshot",
"mcp__puppeteer__puppeteer_fill",
"mcp__puppeteer__puppeteer_click",
"mcp__puppeteer__puppeteer_evaluate",
"Bash(tree:*)"
],
"deny": [],
"ask": []

View File

@@ -1,11 +1,11 @@
# 暫時規範管理系統 V3 - 開發者最佳實踐指南
# PANJIT To-Do System - 開發者最佳實踐指南
> **⚠️ 重要提醒**:本文件包含敏感的系統配置和最佳實踐資訊,僅供開發團隊內部使用。
> 此文件已在 .gitignore 中排除,請勿提交至版本控制系統。
## 🎯 文件目的
本文件記錄在開發暫時規範管理系統 V3 過程中遇到的技術難點及最佳解決方案,避免後續開發者重複踩坑。
本文件記錄在開發 PANJIT To-Do System 過程中遇到的技術難點及最佳解決方案包含前後端整合、資料庫設計、LDAP整合、郵件系統等關鍵技術決策,避免後續開發者重複踩坑。
---
@@ -541,18 +541,549 @@ tar -czf uploads_${DATE}.tar.gz uploads/
---
---
## 🎨 前端開發最佳實踐
### 1. Next.js + TypeScript 架構
**關鍵發現**App Router 架構提供更好的開發體驗和效能。
#### 推薦的專案結構
```
frontend/src/
├── app/ # Next.js 13+ App Router
│ ├── (auth)/ # Route Groups
│ ├── dashboard/ # Dashboard 路由
│ ├── todos/ # 待辦事項頁面
│ ├── layout.tsx # 根版面
│ └── page.tsx # 首頁
├── components/ # React 組件
│ ├── layout/ # 版面組件
│ ├── todos/ # 待辦事項組件
│ └── ui/ # 通用 UI 組件
├── lib/ # 工具函數
├── store/ # Redux 狀態管理
├── types/ # TypeScript 類型定義
└── providers/ # Context Providers
```
#### TypeScript 最佳實踐
```typescript
// types/todo.ts - 完整的類型定義
export interface TodoItem {
id: string;
title: string;
description?: string;
status: 'NEW' | 'DOING' | 'BLOCKED' | 'DONE';
priority: 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT';
due_date?: string;
created_at: string;
creator_ad: string;
starred: boolean;
is_public: boolean;
tags: string[];
responsible_users: string[];
followers: string[];
}
// API 回應類型
export interface ApiResponse<T> {
data: T;
message?: string;
total?: number;
}
```
### 2. Material-UI 整合
**關鍵發現**:主題系統和組件客制化是關鍵。
#### 主題設計
```typescript
// providers/ThemeProvider.tsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
const lightTheme = createTheme({
palette: {
mode: 'light',
primary: {
main: '#3b82f6', // 藍色主題
},
secondary: {
main: '#10b981', // 綠色輔助
},
},
typography: {
fontFamily: '"Noto Sans TC", "Roboto", sans-serif',
},
});
const darkTheme = createTheme({
palette: {
mode: 'dark',
primary: {
main: '#60a5fa',
},
background: {
default: '#0f172a',
paper: '#1e293b',
},
},
});
```
#### 響應式設計
```typescript
// hooks/useResponsive.ts
import { useTheme, useMediaQuery } from '@mui/material';
export const useResponsive = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const isTablet = useMediaQuery(theme.breakpoints.between('md', 'lg'));
const isDesktop = useMediaQuery(theme.breakpoints.up('lg'));
return { isMobile, isTablet, isDesktop };
};
```
### 3. 狀態管理策略
**關鍵發現**Redux Toolkit + React Query 組合提供最佳的開發體驗。
#### Redux Store 設計
```typescript
// store/todoSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface TodoState {
filterMode: 'all' | 'created' | 'responsible' | 'following';
appliedFilters: TodoFilters;
selectedItems: string[];
viewMode: 'list' | 'card' | 'calendar';
}
const todoSlice = createSlice({
name: 'todo',
initialState,
reducers: {
setFilterMode: (state, action: PayloadAction<FilterMode>) => {
state.filterMode = action.payload;
},
toggleSelectItem: (state, action: PayloadAction<string>) => {
const id = action.payload;
if (state.selectedItems.includes(id)) {
state.selectedItems = state.selectedItems.filter(item => item !== id);
} else {
state.selectedItems.push(id);
}
},
},
});
```
#### React Query 集成
```typescript
// lib/api/todos.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
export const useTodos = (filters: TodoFilters) => {
return useQuery({
queryKey: ['todos', filters],
queryFn: () => fetchTodos(filters),
staleTime: 30000, // 30秒內數據視為新鮮
});
};
export const useCreateTodo = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: createTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] });
toast.success('待辦事項建立成功!');
},
onError: (error) => {
toast.error(error.message || '建立失敗');
},
});
};
```
---
## 🔄 後端 API 設計最佳實踐
### 1. Flask 應用架構
**關鍵發現**Blueprint 和工廠模式提供最佳的可維護性。
#### 應用程式工廠模式
```python
# app.py - 推薦的應用程式結構
def create_app(config_name=None):
if config_name is None:
config_name = os.environ.get('FLASK_ENV', 'development')
app = Flask(__name__)
app.config.from_object(config[config_name])
# 初始化擴展
db.init_app(app)
migrate.init_app(app, db)
jwt.init_app(app)
mail.init_app(app)
CORS(app, origins=app.config['CORS_ORIGINS'])
# 註冊 Blueprint
from routes import register_blueprints
register_blueprints(app)
# 設定錯誤處理
setup_error_handlers(app)
return app
```
#### RESTful API 設計
```python
# routes/todos.py - 標準化的 API 結構
@todos_bp.route('', methods=['GET'])
@jwt_required()
def get_todos():
try:
# 參數驗證
page = request.args.get('page', 1, type=int)
per_page = min(request.args.get('per_page', 20, type=int), 100)
# 業務邏輯
todos, total = todo_service.get_user_todos(
user_ad=get_jwt_identity(),
page=page,
per_page=per_page,
filters=request.args
)
# 統一回應格式
return jsonify({
'data': [todo.to_dict() for todo in todos],
'pagination': {
'page': page,
'per_page': per_page,
'total': total,
'pages': (total + per_page - 1) // per_page
}
}), 200
except ValidationError as e:
return jsonify({'error': str(e)}), 400
except Exception as e:
logger.error(f"Error getting todos: {str(e)}")
return jsonify({'error': 'Internal server error'}), 500
```
### 2. 資料驗證策略
**關鍵發現**:輸入驗證和序列化分離提供更好的可維護性。
```python
# validators/todo.py
from marshmallow import Schema, fields, validate
class CreateTodoSchema(Schema):
title = fields.Str(required=True, validate=validate.Length(min=1, max=200))
description = fields.Str(missing=None, validate=validate.Length(max=2000))
status = fields.Str(missing='NEW', validate=validate.OneOf(['NEW', 'DOING', 'BLOCKED', 'DONE']))
priority = fields.Str(missing='MEDIUM', validate=validate.OneOf(['LOW', 'MEDIUM', 'HIGH', 'URGENT']))
due_date = fields.Date(missing=None)
responsible_users = fields.List(fields.Str(), missing=list)
followers = fields.List(fields.Str(), missing=list)
tags = fields.List(fields.Str(), missing=list)
is_public = fields.Bool(missing=False)
starred = fields.Bool(missing=False)
# 使用裝飾器進行驗證
def validate_json(schema):
def decorator(f):
def wrapper(*args, **kwargs):
try:
data = schema.load(request.json or {})
return f(data, *args, **kwargs)
except ValidationError as e:
return jsonify({'error': e.messages}), 400
return wrapper
return decorator
@todos_bp.route('', methods=['POST'])
@jwt_required()
@validate_json(CreateTodoSchema())
def create_todo(data):
# 已驗證的資料直接使用
todo = todo_service.create_todo(
creator_ad=get_jwt_identity(),
**data
)
return jsonify({'data': todo.to_dict()}), 201
```
### 3. 服務層架構
**關鍵發現**:業務邏輯分離到服務層提供更好的測試性。
```python
# services/todo_service.py
class TodoService:
def __init__(self):
self.logger = get_logger(__name__)
def create_todo(self, creator_ad: str, **kwargs) -> TodoItem:
"""建立新的待辦事項"""
try:
# 驗證負責人帳號
if kwargs.get('responsible_users'):
valid_users = validate_ad_accounts(kwargs['responsible_users'])
if len(valid_users) != len(kwargs['responsible_users']):
invalid_users = set(kwargs['responsible_users']) - set(valid_users.keys())
raise ValidationError(f"無效的負責人帳號: {', '.join(invalid_users)}")
# 建立待辦事項
todo = TodoItem(
title=kwargs['title'],
description=kwargs.get('description'),
status=kwargs.get('status', 'NEW'),
priority=kwargs.get('priority', 'MEDIUM'),
due_date=kwargs.get('due_date'),
creator_ad=creator_ad,
is_public=kwargs.get('is_public', False),
starred=kwargs.get('starred', False),
tags=kwargs.get('tags', [])
)
# 設定使用者資訊
user_info = get_user_info(creator_ad)
if user_info:
todo.creator_display_name = user_info['display_name']
todo.creator_email = user_info['email']
db.session.add(todo)
db.session.flush() # 取得 ID
# 新增負責人和追蹤者
self._add_users_to_todo(todo.id, kwargs.get('responsible_users', []), 'responsible')
self._add_users_to_todo(todo.id, kwargs.get('followers', []), 'follower')
db.session.commit()
# 發送通知
self._send_assignment_notifications(todo)
# 記錄稽核日誌
self._log_audit(todo.id, creator_ad, 'CREATE', '建立待辦事項')
return todo
except Exception as e:
db.session.rollback()
self.logger.error(f"Error creating todo: {str(e)}")
raise
```
---
## 📊 Excel 處理最佳實踐
### 1. 安全的檔案處理
**關鍵發現**:檔案上傳和處理需要多層驗證。
```python
# utils/excel_utils.py
import pandas as pd
from openpyxl import load_workbook
import tempfile
import os
class ExcelProcessor:
ALLOWED_EXTENSIONS = {'.xlsx', '.xls', '.csv'}
MAX_FILE_SIZE = 16 * 1024 * 1024 # 16MB
MAX_ROWS = 10000
def validate_file(self, file):
"""檔案安全驗證"""
# 檔案大小檢查
if len(file.read()) > self.MAX_FILE_SIZE:
raise ValidationError("檔案大小超過限制 (16MB)")
file.seek(0) # 重置檔案指針
# 檔案類型檢查
filename = secure_filename(file.filename)
if not any(filename.lower().endswith(ext) for ext in self.ALLOWED_EXTENSIONS):
raise ValidationError("不支援的檔案格式")
return filename
def parse_excel_file(self, file):
"""安全的 Excel 解析"""
try:
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
file.save(temp_file.name)
# 使用 pandas 讀取檔案
if temp_file.name.endswith('.csv'):
df = pd.read_csv(temp_file.name, encoding='utf-8')
else:
df = pd.read_excel(temp_file.name)
# 行數限制
if len(df) > self.MAX_ROWS:
raise ValidationError(f"資料列數超過限制 ({self.MAX_ROWS})")
return self.validate_and_transform_data(df)
finally:
# 清理暫存檔案
if 'temp_file' in locals():
os.unlink(temp_file.name)
def validate_and_transform_data(self, df):
"""資料驗證和轉換"""
required_columns = ['標題', '負責人']
missing_columns = [col for col in required_columns if col not in df.columns]
if missing_columns:
raise ValidationError(f"缺少必要欄位: {', '.join(missing_columns)}")
validated_data = []
errors = []
for index, row in df.iterrows():
try:
todo_data = self.validate_row(row, index + 2) # +2 因為標題行
validated_data.append(todo_data)
except ValidationError as e:
errors.append(f"第 {index + 2} 行: {str(e)}")
return {
'data': validated_data,
'errors': errors,
'total': len(df)
}
```
### 2. 模板生成
**關鍵發現**:動態模板生成提供更好的使用者體驗。
```python
# routes/excel.py
@excel_bp.route('/template', methods=['GET'])
@jwt_required()
def download_template():
"""生成並下載 Excel 匯入模板"""
try:
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.worksheet.datavalidation import DataValidation
wb = Workbook()
ws = wb.active
ws.title = "待辦事項匯入模板"
# 標題行
headers = [
'標題*', '描述', '狀態', '優先級',
'到期日', '負責人*', '追蹤人員', '標籤', '備註'
]
# 設定標題樣式
title_font = Font(bold=True, color='FFFFFF')
title_fill = PatternFill(start_color='366092', end_color='366092', fill_type='solid')
for col, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col, value=header)
cell.font = title_font
cell.fill = title_fill
cell.alignment = Alignment(horizontal='center')
# 資料驗證
status_validation = DataValidation(
type="list",
formula1='"NEW,DOING,BLOCKED,DONE"',
showErrorMessage=True,
errorTitle="狀態錯誤",
error="請選擇: NEW, DOING, BLOCKED, DONE"
)
priority_validation = DataValidation(
type="list",
formula1='"LOW,MEDIUM,HIGH,URGENT"',
showErrorMessage=True,
errorTitle="優先級錯誤",
error="請選擇: LOW, MEDIUM, HIGH, URGENT"
)
ws.add_data_validation(status_validation)
ws.add_data_validation(priority_validation)
status_validation.add(f'C2:C{MAX_ROWS}')
priority_validation.add(f'D2:D{MAX_ROWS}')
# 範例資料
sample_data = [
['完成月報撰寫', '包含各部門數據統計和分析', 'NEW', 'HIGH', '2024/01/15', 'user1', 'manager1', '報告,月度', '請於期限內完成'],
['系統維護檢查', '定期檢查伺服器狀態', 'DOING', 'MEDIUM', '2024/01/20', 'user2', 'user1,user3', 'IT,維護', ''],
]
for row, data in enumerate(sample_data, 2):
for col, value in enumerate(data, 1):
ws.cell(row=row, column=col, value=value)
# 調整欄寬
column_widths = [20, 30, 12, 12, 12, 15, 20, 15, 20]
for col, width in enumerate(column_widths, 1):
ws.column_dimensions[ws.cell(row=1, column=col).column_letter].width = width
# 生成檔案
from io import BytesIO
output = BytesIO()
wb.save(output)
output.seek(0)
return send_file(
output,
as_attachment=True,
download_name=f'todo_import_template_{datetime.now().strftime("%Y%m%d")}.xlsx',
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
except Exception as e:
logger.error(f"Error generating template: {str(e)}")
return jsonify({'error': '模板生成失敗'}), 500
```
---
## 📝 總結
本文件記錄了開發暫時規範管理系統 V3 過程中的關鍵技術決策和最佳實踐。這些經驗可以幫助後續開發者:
本文件記錄了開發 PANJIT To-Do System 過程中的關鍵技術決策和最佳實踐。這些經驗可以幫助後續開發者:
1. **避免常見陷阱**:特別是 LDAP 配置和 SMTP 設定
2. **提升開發效率**:使用經過驗證的架構模式
3. **確保系統穩定性**:採用完整的錯誤處理和監控機制
4. **簡化部署流程**:使用 Docker 和自動化腳本
1. **避免常見陷阱**:特別是 LDAP 配置、前後端整合、Excel 處理
2. **提升開發效率**:使用經過驗證的架構模式和工具鏈
3. **確保程式碼品質**:遵循 TypeScript、Python 最佳實踐
4. **提升使用者體驗**:響應式設計、效能優化、錯誤處理
5. **簡化維護工作**:清晰的架構分離、完整的日誌記錄
**重要技術決策總結**
- **前端**Next.js 14 App Router + TypeScript + Material-UI + Redux Toolkit
- **後端**Flask + SQLAlchemy + Celery + Redis + JWT
- **資料庫**MySQL 8.0 + 適當索引設計
- **部署**Docker + Nginx + 健康檢查
**重要提醒**:本文件包含敏感資訊,請勿外洩或提交至公開版本控制系統。
---
*最後更新2025年1月*
*文件版本V1.0*
*文件版本V2.0*
*適用系統PANJIT To-Do System v1.0*

View File

@@ -1,149 +0,0 @@
# 對話記憶 - PANJIT To-Do List System V1
## 最新狀態 (2025-08-29)
### 已完成的主要功能
1. **Fire Email 功能修復** - 修正 AD 帳號轉換郵件地址的問題
2. **重複錯誤提示修復** - 解決 axios 攔截器重複顯示錯誤的問題
3. **增強型郵件通知設定** - 支援彈性提醒天數、週/月摘要
4. **CORS 網路錯誤修復** - 新增 port 3002 支援
5. **通知系統實作** - 完整的通知顯示與互動功能
6. **通知面板互動功能** - 查看、標記已讀等按鈕功能完成
7. **公開/私人 Todo 功能** - ✅ 完整實現並測試通過
8. **載入效能優化** - ✅ 添加骨架屏 Loading 狀態
### 核心技術架構
- **前端**: Next.js 14 + TypeScript + Material-UI + React Hook Form
- **後端**: Flask + SQLAlchemy + JWT + MySQL
- **認證**: LDAP 整合 + JWT Token 刷新機制
- **郵件**: SMTP 服務整合 (mail.panjit.com.tw:25)
- **資料庫**: MySQL with enhanced notification models
### 重要修復記錄
#### 1. Fire Email 核心問題修復
**檔案**: `backend/utils/email_service.py:_get_user_email`
```python
# 修正前
user_info.get('mail') # 錯誤的欄位名稱
# 修正後
user_info.get('email') # 正確的欄位名稱
```
#### 2. 通知系統 API 實作
**檔案**: `backend/routes/notifications.py`
- 新增 `/api/notifications/` - 獲取用戶通知
- 新增 `/api/notifications/mark-read` - 標記單個通知已讀
- 新增 `/api/notifications/mark-all-read` - 標記全部通知已讀
#### 3. 前端通知面板功能
**檔案**: `frontend/src/components/layout/NotificationPanel.tsx`
- 實作查看按鈕 - 導航到對應 todo
- 實作標記已讀按鈕 - 更新通知狀態
- 實作全部標記已讀 - 批量更新
- 實作查看全部 - 導航到主頁
### 資料庫模型增強
**檔案**: `backend/models.py`
```python
class TodoUserPref(db.Model):
monthly_summary_enabled = db.Column(db.Boolean, default=False)
reminder_days_before = db.Column(JSON, default=lambda: [1, 3])
weekly_summary_time = db.Column(db.String(5), default='09:00')
monthly_summary_time = db.Column(db.String(5), default='09:00')
# ... 其他增強欄位
```
### 2025-08-29 修復進度記錄
#### ✅ 已完成修復
1. **公開任務頁面 showSnackbar 錯誤**
- 移除錯誤的 `showSnackbar` 導入,替換為 `react-hot-toast`
- 將公開任務頁面包裝在 `DashboardLayout`
2. **公開/私人 Todo 功能完整實現**
- 資料庫:成功新增 `is_public``tags` 欄位
- 後端 API完整實現公開 todo 查詢、追蹤、可見性切換功能
- 跨用戶測試:成功驗證權限控制正確運作
3. **載入效能和 Loading 狀態改善**
- 為所有頁面添加詳細的骨架屏 loading 狀態
- 使用 Material-UI `Skeleton` 組件提供流暢的使用者體驗
4. **編譯錯誤修復**
- 修復 `Sidebar.tsx` 中圖標導入錯誤
- 重新編寫 `dashboard/page.tsx` 解決 JSX 語法錯誤
- 清理 Next.js 緩存,確保前端在 3000 端口正常運行
#### ❌ 實際測試後仍需修復的問題
根據用戶實際測試結果:
1. **Sidebar 消失問題 - 未修復**
- 問題:打開篩選功能時 sidebar 仍會消失,需要重新整理頁面
- 待處理:檢查 DashboardLayout 的狀態管理和動畫邏輯
2. **篩選功能不正常運作 - 未修復**
- 問題:根本不會照著篩選條件顯示結果
- 待處理:重新檢查前端篩選邏輯的實際執行
### 公開 Todo 功能實現詳情 (已完成)
#### 後端 API 端點
- `GET /api/todos/public` - 獲取公開 todos
- `GET /api/todos/following` - 獲取追蹤的 todos
- `PATCH /api/todos/<id>/visibility` - 切換可見性
- `POST /api/todos/<id>/follow` - 追蹤 todo
- `DELETE /api/todos/<id>/follow` - 取消追蹤
#### 測試帳號 (已驗證)
- ymirliu@panjit.com.tw (密碼: 3EDC4rfv5tgb)
- uthuang@panjit.com.tw (密碼: 3EDC4rfv5tgb)
### 待修復問題清單
1. **Sidebar 消失問題** - 需要檢查狀態管理衝突
2. **篩選功能實際運作** - 需要重新測試和調試前端邏輯
3. **通知已讀狀態持久化** - 目前僅在記憶體中,需要資料庫儲存
### 環境配置
```bash
# 前端 (Port 3000)
cd frontend && npm run dev
# 後端 (Port 5000)
cd backend && ./venv/Scripts/activate && python app.py
```
### 測試用戶帳號
- **uthuang** (92509) - uthuang@panjit.com.tw
- **ymirliu** - ymirliu@panjit.com.tw
- **minjiesyu** (92453) - minjiesyu@panjit.com.tw
### API 端點清單
- `GET /api/notifications/` - 獲取通知清單
- `POST /api/notifications/mark-read` - 標記單個通知已讀
- `POST /api/notifications/mark-all-read` - 標記全部通知已讀
- `POST /api/notifications/fire-email` - 發送緊急郵件
- `GET/PATCH /api/notifications/settings` - 通知設定管理
### 重要設定檔案
- **後端 .env**: 包含 CORS_ORIGINS 設定 (支援 3000,3001,3002)
- **前端 api.ts**: 包含完整的 notificationsApi 客戶端
- **資料庫連線**: mysql.theaken.com:33306/db_A060
## 開發原則提醒
1. 必須提供完整可執行的程式碼
2. 所有功能都需要單元測試
3. 確保 Windows 環境相容性
4. 遵循 MUI 設計規範
5. 實作適當的錯誤處理
---
## 系統當前狀態
- **前端**: http://localhost:3000 ✅ 正常編譯運行
- **後端**: http://localhost:5000 ✅ 正常運行
- **公開任務功能**: ✅ 完全正常
- **載入狀態**: ✅ 已優化
- **篩選功能**: ❌ 需要修復 (不會照著篩選)
- **Sidebar**: ❌ 消失問題需要修復 (打開篩選時消失)
*最後更新: 2025-08-29 18:50 - 根據實際測試結果更新*

176
PRD.md
View File

@@ -1,176 +0,0 @@
# PANJITTo-Do ListWeb UIV1 產品需求文件PRD
**版本**V1定版
**最後更新**2025-08-28
**資料庫**MySQL所有資料表皆採前綴 `todo_`
**登入**AD/LDAP不限僅內網
**DueDate 精度**:到 **「日」**
**Email 寄件者**:以**建立者的 AD Mail**發送SMTP 需允許代寄或以 Envelope From 配合)
**Excel 匯入**提供正式模板含下拉驗證、README
---
## 1. 背景與目標
- 以 AD 帳號辨識使用者,提供個人/協作化的待辦管理。
- 除固定排程提醒外,提供「**Fire 一鍵提醒**」降低漏辦風險。
- 提供**正式 Excel 模板**以降低匯入錯誤率。
### 成功指標(示例)
- 90% 使用者在 2 週內完成首次建立/匯入待辦。
- 逾期數較導入前下降 30%。
- 主要操作 P95 < 1s匯入任務成功率 99%。
---
## 2. 使用者與場景
- **建立者**建立待辦者預設可見/可編輯
- **負責人多人**可見/可編輯與建立者同等)。
- **追蹤者多人**可見但預設不可編輯可收信
主要場景
1) 新增/編輯待辦可設定多負責人多追蹤者)。
2) 清單/日曆檢視篩選批次操作
3) Fire 一鍵提醒立即寄發可寫附註冷卻與限額管控
4) 排程提醒到期前/當天/逾期 + 週摘要可開關)。
5) 匯入下載模板填寫上傳驗證導入
---
## 3. 功能需求
### 3.1 待辦 CRUD 與視圖
- 欄位
- 必填`title`
- 選填`description`, `priority(LOW|MEDIUM|HIGH|URGENT)`, `status(NEW|DOING|BLOCKED|DONE)`, `due_date(YYYY-MM-DD)`, `starred`
- 系統`id(uuid)`, `created_at`, `completed_at`, `creator_ad`, `creator_display_name`, `creator_email`
- 視圖列表 + 日曆支援篩選狀態到期區間加星與批次操作狀態到期日)。
- 可見性建立者/負責人/追蹤者可見可編輯者為建立者與負責人
### 3.2 多負責人/多追蹤者
- AD 帳號多選加入維護表 `todo_item_responsible`, `todo_item_follower`
### 3.3 Email 通知
- **排程提醒**可開關到期前 X 到期日逾期 Y 週一 09:00 摘要建議)。
- **Fire 一鍵提醒**
- 受信人預設負責人 + 追蹤者 + 建立者可調整/去重)。
- 冷卻/限額**同一待辦 2 分鐘冷卻****每人每日 20 **。
- 可附註所有寄送寫入 `todo_mail_log`
### 3.4 Excel 匯入
- 下載正式模板 README 與下拉驗證)。
- 驗證必填日期格式AD 帳號存在性重複同標題 + 近日期)。
- 逐列錯誤報告與問題列下載」。
---
## 4. 非功能需求
- 效能一般操作 P95 < 1s匯入以背景 Job 執行提供進度查詢
- 可用性SMTP 故障不影響 CRUD提供降級邏輯
- 監控`/healthz`DB/SMTP寄送/匯入皆留 `todo_audit_log`
- 備份每日快照保留 7/30
---
## 5. 資料庫MySQL前綴 `todo_`
- `todo_item`主表待辦
- `todo_item_responsible`多負責人
- `todo_item_follower`多追蹤者
- `todo_mail_log`排程/Fire 寄信紀錄
- `todo_audit_log`稽核日誌
- `todo_user_pref`使用者偏好
```mermaid
erDiagram
todo_item ||--o{ todo_item_responsible : has
todo_item ||--o{ todo_item_follower : has
todo_item ||--o{ todo_mail_log : logs
todo_item ||--o{ todo_audit_log : audits
todo_item {{
char(36) id PK
varchar title
text description
enum status
enum priority
date due_date
datetime created_at
datetime completed_at
varchar creator_ad
varchar creator_display_name
varchar creator_email
tinyint starred
}}
todo_item_responsible {{
char(36) todo_id FK
varchar ad_account
datetime added_at
}}
todo_item_follower {{
char(36) todo_id FK
varchar ad_account
datetime added_at
}}
todo_mail_log {{
bigint id PK
char(36) todo_id FK
enum type
varchar triggered_by_ad
text recipients
varchar subject
enum status
varchar provider_msg_id
text error_text
datetime created_at
datetime sent_at
}}
todo_audit_log {{
bigint id PK
varchar actor_ad
char(36) todo_id FK nullable
enum action
json detail
datetime created_at
}}
todo_user_pref {{
varchar ad_account PK
varchar email
datetime updated_at
}}
```
---
## 6. API摘要
- `GET /api/todos``POST /api/todos``PATCH /api/todos/{{id}}``DELETE /api/todos/{{id}}`
- `POST /api/todos/{{id}}/responsibles``POST /api/todos/{{id}}/followers`
- `POST /api/todos/{{id}}/fire-email`
- `GET /api/imports/template``POST /api/imports``GET /api/imports/{{job_id}}`
---
## 7. 驗收標準
1) AD 登入成功首登寫入個資
2) 多負責人/多追蹤者運作可見/可編輯權限如預期
3) Fire 寄信預設收件人冷卻/限額附註寄送紀錄
4) 排程提醒週摘要可開關且寄送正確
5) 匯入模板下載驗證逐列錯誤成功導入
6) 稽核CRUD/匯入/寄信皆可查
---
## 8. 風險與對策
- SMTP 代寄受限 以系統 Envelope From + `Reply-To:` 建立者
- 匯入錯誤率高 強制模板下拉驗證逐列錯誤檔回饋
---
## 9. 附件
- 正式 Excel 模板`todo_import_template_v1_formal.xlsx`

View File

@@ -1,16 +1,32 @@
# PANJIT To-Do List System V1
# PANJIT To-Do System
一個基於 Next.js + Flask 的企業級待辦事項管理系統,支援 AD/LDAP 登入、多人協作、Email 提醒等功能。
一個功能完整的企業級待辦事項管理系統,支援 LDAP 認證、郵件通知、Excel 匯入匯出,以及豐富的協作功能。
## 🚀 系統特色
## 🚀 功能特色
-**AD/LDAP 登入** - 企業級身份驗證
- **多人協作** - 支援多負責人/多追蹤者
- **Fire 一鍵提醒** - 立即郵件提醒功能 (2分鐘冷卻 + 每日20封限額)
- **排程提醒** - 到期前/當天/逾期自動提醒 + 週摘要
- **Excel 匯入** - 完整模板驗證與錯誤處理
- **完整稽核** - 所有操作記錄追蹤
-**響應式設計** - 支援桌面與行動裝置
### 核心功能
- **待辦事項管理**:建立、編輯、刪除、狀態管理
- **多人協作**:負責人指派、追蹤人員、權限控制
- **狀態管理**:新建立 → 進行中 → 已阻礙 → 已完成
- **優先級分類**:低、中、高、緊急
- **到期日管理**:日期設定、逾期提醒
### 高級功能
- **LDAP/Active Directory 整合**:企業帳號統一認證
- **智能搜尋**:模糊搜尋、多條件篩選
- **Excel 匯入匯出**:批量資料處理
- **郵件通知系統**:自動提醒、狀態變更通知
- **行事曆檢視**:時間軸管理
- **批量操作**:多項目同時處理
- **公開/私人模式**:靈活的可見性控制
### 技術特色
- **現代化架構**:前後端分離設計
- **響應式設計**:支援桌面和行動裝置
- **深色/淺色主題**:使用者體驗優化
- **即時更新**React Query 資料同步
- **任務排程**Celery 背景處理
- **健康檢查**:系統狀態監控
## 🏗️ 技術架構

View File

@@ -51,10 +51,15 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
const { user, logout } = useAuth();
const { themeMode, actualTheme, setThemeMode } = useTheme();
const muiTheme = useMuiTheme();
const isMobile = useMediaQuery(muiTheme.breakpoints.down('lg'));
const isMobile = useMediaQuery('(max-width: 1200px)'); // 降低斷點確保覆蓋所有小螢幕
// 響應式處理
useEffect(() => {
console.log('Responsive handling:', {
isMobile,
windowWidth: window.innerWidth,
currentSidebarOpen: sidebarOpen
});
if (isMobile) {
setSidebarOpen(false);
setSidebarCollapsed(false);
@@ -136,10 +141,27 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
};
const toggleSidebar = () => {
const toggleSidebar = (event?: React.MouseEvent) => {
console.log('🔧 Toggle sidebar clicked:', {
isMobile,
sidebarOpen,
sidebarCollapsed,
windowWidth: window.innerWidth,
eventTarget: event?.target,
eventCurrentTarget: event?.currentTarget
});
// 防止事件冒泡
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (isMobile) {
console.log('📱 Mobile: Setting sidebar open to:', !sidebarOpen);
setSidebarOpen(!sidebarOpen);
} else {
console.log('🖥️ Desktop: Toggling collapsed to:', !sidebarCollapsed);
setSidebarCollapsed(!sidebarCollapsed);
}
};
@@ -162,8 +184,8 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
position="fixed"
elevation={0}
sx={{
width: { lg: `calc(100% - ${getDrawerWidth()}px)` },
ml: { lg: `${getDrawerWidth()}px` },
width: isMobile ? '100%' : `calc(100% - ${getDrawerWidth()}px)`,
ml: isMobile ? 0 : `${getDrawerWidth()}px`,
backgroundColor: actualTheme === 'dark'
? 'rgba(17, 24, 39, 0.9)'
: 'rgba(255, 255, 255, 0.9)',
@@ -183,11 +205,23 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
onClick={toggleSidebar}
sx={{
mr: 2,
display: { lg: sidebarCollapsed ? 'inline-flex' : 'none' },
display: isMobile || sidebarCollapsed ? 'flex' : 'none',
zIndex: 1301, // 確保按鈕在 Drawer modal 之上
position: 'relative',
pointerEvents: 'auto',
cursor: 'pointer',
minWidth: '48px',
minHeight: '48px',
border: process.env.NODE_ENV === 'development' ? '2px solid lime' : 'none', // 更明顯的除錯邊框
'&:hover': {
backgroundColor: actualTheme === 'dark'
? 'rgba(255, 255, 255, 0.1)'
: 'rgba(0, 0, 0, 0.1)',
},
'&:active': {
backgroundColor: actualTheme === 'dark'
? 'rgba(255, 255, 255, 0.2)'
: 'rgba(0, 0, 0, 0.2)',
}
}}
>
@@ -303,6 +337,9 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
}}
ModalProps={{
keepMounted: true, // 手機端性能優化
style: {
zIndex: isMobile ? 1300 : undefined, // 確保 modal 不會遮擋按鈕
},
}}
>
<Sidebar
@@ -317,7 +354,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
component="main"
sx={{
flexGrow: 1,
width: { lg: `calc(100% - ${getDrawerWidth()}px)` },
width: isMobile ? '100%' : `calc(100% - ${getDrawerWidth()}px)`,
minHeight: '100vh',
backgroundColor: actualTheme === 'dark' ? '#111827' : '#f9fafb',
transition: 'width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',

469
usermanual.md Normal file
View File

@@ -0,0 +1,469 @@
# PANJIT To-Do System 使用者手冊
## 📖 目錄
1. [系統簡介](#系統簡介)
2. [登入系統](#登入系統)
3. [主要功能](#主要功能)
4. [待辦事項管理](#待辦事項管理)
5. [協作功能](#協作功能)
6. [通知設定](#通知設定)
7. [Excel 匯入匯出](#excel-匯入匯出)
8. [進階功能](#進階功能)
9. [常見問題](#常見問題)
---
## 系統簡介
PANJIT To-Do System 是一個專為企業環境設計的待辦事項管理系統,提供:
- **統一登入**:使用公司 AD/LDAP 帳號直接登入
- **多人協作**:支援團隊合作、責任分工
- **智能通知**:自動化郵件提醒,不錯過任何重要任務
- **數據管理**Excel 批量匯入匯出,高效處理大量資料
- **行動支援**:響應式設計,桌面和行動裝置完美適配
---
## 登入系統
### 🔐 第一次登入
1. **開啟系統**
- 瀏覽器開啟:`http://your-company-domain.com`
- 系統支援Chrome、Firefox、Safari、Edge
2. **輸入帳號密碼**
- 使用者名稱:`帳號@panjit.com.tw``帳號`
- 密碼:與 Windows 登入相同
3. **首次登入設定**
- 系統會自動從 AD 取得您的姓名和 Email
- 建立個人偏好設定
- 設定預設通知選項
### ⚙️ 登入選項
- **記住我**勾選後下次自動登入7天內有效
- **語言切換**:支援繁體中文、英文
- **主題模式**:淺色/深色主題切換
---
## 主要功能
### 📱 系統介面
#### 頂部導航欄
- **系統標題**:顯示目前頁面
- **搜尋列**:快速搜尋待辦事項
- **通知鈴鐺**:系統通知提醒
- **使用者頭像**:個人設定選單
#### 左側選單
- **儀表板**:系統概覽和統計
- **待辦清單**:主要工作區域
- **行事曆**:時間軸檢視
- **設定**:個人化設定
#### 主要工作區
- **工具列**:篩選、排序、批量操作
- **清單檢視**:條列式顯示
- **卡片檢視**:圖像化顯示
- **行事曆檢視**:時間軸顯示
---
## 待辦事項管理
### 建立新待辦事項
1. **點選「新增待辦」按鈕**
- 位於右上角藍色按鈕
- 快捷鍵:`Ctrl + N`
2. **填寫基本資訊**
```
標題*:簡潔描述任務內容
描述:詳細說明和注意事項
狀態:新建立 (預設)
優先級:中 (預設)
到期日:選擇完成期限
```
3. **指派人員**
- **負責人**:執行任務的人員
- 支援多人負責
- 可搜尋公司同事姓名或帳號
- 自動驗證帳號存在性
- **追蹤人員**:需要了解進度的人員
- 主管或相關部門同事
- 會收到狀態變更通知
4. **進階設定**
- **標籤**:分類標記(可自訂)
- **星號標記**:重要項目標示
- **公開/私人**:可見性設定
### ✏️ 編輯待辦事項
1. **開啟編輯模式**
- 點選事項標題直接編輯
- 或點選「編輯」按鈕
2. **權限說明**
- **建立者**:完整編輯權限
- **負責人**:可修改狀態、描述
- **追蹤人員**:僅可查看
3. **狀態變更**
- **新建立** → **進行中**:開始執行
- **進行中** → **已阻礙**:遇到困難需協助
- **已阻礙** → **進行中**:問題解決繼續執行
- **進行中** → **已完成**:任務完成
### 🔍 搜尋和篩選
#### 快速搜尋
- **關鍵字搜尋**:標題、描述、人員姓名
- **模糊比對**:不需輸入完整字詞
- **即時搜尋**:輸入即時顯示結果
#### 進階篩選
1. **點選篩選按鈕**(漏斗圖示)
2. **設定篩選條件**
- 狀態:單選或多選
- 優先級:依重要程度篩選
- 指派人員:查看特定人員的任務
- 日期範圍:到期日區間
- 標籤:依分類查看
3. **常用篩選**
- 我負責的:顯示自己的任務
- 我追蹤的:顯示關注的項目
- 逾期項目:已過期未完成
- 本週到期:七天內到期
#### 排序選項
- **到期日**:依時間緊急程度
- **優先級**:依重要程度
- **建立時間**:依新舊程度
- **狀態**:依進度分組
- **標題**:字母順序
---
## 協作功能
### 👥 團隊協作
#### 角色說明
- **建立者**:任務發起人,擁有完整權限
- **負責人**:實際執行者,可編輯任務內容
- **追蹤人員**:關注者,可查看進度並接收通知
#### 協作流程
1. **任務指派**
```
建立者 → 指派負責人 → 設定追蹤人員 → 發送通知
```
2. **進度更新**
```
負責人更新狀態 → 系統記錄變更 → 自動通知相關人員
```
3. **問題處理**
```
遇到阻礙 → 標記為「已阻礙」→ 通知建立者/追蹤人員 → 協助解決
```
### 🔔 即時通知
#### Fire 一鍵提醒
- **功能說明**:立即發送郵件提醒
- **使用時機**:急件處理、重要提醒
- **限制機制**
- 2分鐘冷卻時間
- 每日20封限額
- 防止過度騷擾
#### 自動化通知
- **到期前提醒**3天前自動發送
- **當天提醒**:到期當日早上通知
- **逾期提醒**逾期1天後提醒
- **狀態變更**:任務狀態改變時通知
#### 週摘要報告
- **發送時間**每週一早上9點
- **內容包含**
- 本週待完成任務
- 逾期項目統計
- 新指派任務
- 完成項目回顧
---
## 通知設定
### 📧 郵件通知設定
1. **開啟設定頁面**
- 點選右上角個人頭像
- 選擇「通知設定」
2. **通知類型設定**
- ✅ 新任務指派通知
- ✅ 任務狀態變更通知
- ✅ 到期提醒通知
- ✅ Fire 一鍵提醒
- ✅ 週摘要報告
3. **時間設定**
- **提醒天數**到期前幾天提醒1-7天
- **工作時間**僅工作時間發送9:00-18:00
- **週末通知**:是否包含週末
4. **郵件格式**
- **HTML 格式**:豐富內容顯示
- **純文字格式**:相容性更好
- **摘要模式**:減少郵件數量
### 🔕 勿擾模式
- **暫停所有通知**:臨時關閉通知
- **例外設定**:緊急通知例外
- **自動恢復**:設定恢復時間
---
## Excel 匯入匯出
### 📥 匯入待辦事項
#### Step 1下載模板
1. **點選「Excel 匯入」按鈕**
2. **下載標準模板**
- 包含所有必要欄位
- 內建格式驗證
- 範例資料參考
#### Step 2填寫資料
```excel
標題* | 描述 | 狀態 | 優先級 | 到期日 | 負責人* | 追蹤人員
完成報告撰寫 | 月報內容 | NEW | HIGH | 2024/1/15 | user1 | user2,user3
系統維護 | 定期檢查 | DOING | MEDIUM | 2024/1/20 | user2 | user1
```
**欄位說明:**
- `*` 為必填欄位
- 狀態NEW, DOING, BLOCKED, DONE
- 優先級LOW, MEDIUM, HIGH, URGENT
- 日期格式YYYY/MM/DD
- 人員:使用帳號,多人用逗號分隔
#### Step 3上傳檔案
1. **選擇檔案**:支援 .xlsx, .xls, .csv
2. **系統驗證**
- 格式檢查
- 欄位驗證
- 人員帳號確認
- 重複項目檢查
3. **預覽確認**
- 顯示將匯入的資料
- 標示錯誤項目
- 提供修正建議
4. **執行匯入**
- 成功項目批量建立
- 失敗項目詳細報告
- 自動發送通知
### 📤 匯出待辦事項
#### 匯出選項
1. **全部匯出**:所有可存取的待辦事項
2. **篩選匯出**:根據目前篩選條件
3. **選取匯出**:勾選特定項目
4. **範圍匯出**:指定日期範圍
#### 檔案格式
- **Excel 格式**:完整資料和格式
- **CSV 格式**:純資料,相容性好
- **PDF 報表**:列印友好格式
#### 匯出內容
- 基本資訊:標題、描述、狀態、優先級
- 時間資訊:建立時間、到期日、完成時間
- 人員資訊:建立者、負責人、追蹤人員
- 進階資訊:標籤、備註、操作記錄
---
## 進階功能
### 📊 統計報表
#### 個人統計
- **任務完成率**:本週/本月完成統計
- **平均處理時間**:從建立到完成的時間
- **優先級分佈**:高/中/低優先級比例
- **逾期分析**:逾期項目和原因分析
#### 團隊統計
- **部門效率**:各部門完成情況
- **工作量分析**:人員任務負荷
- **協作頻率**:跨部門合作統計
- **趨勢分析**:月度/季度趨勢
#### 系統統計
- **使用者活躍度**:登入和操作頻率
- **功能使用率**:各功能使用統計
- **效能監控**:系統回應時間
- **錯誤率統計**:系統穩定性指標
### 📅 行事曆整合
#### 檢視模式
- **月檢視**:整月任務概覽
- **週檢視**:週計劃詳細檢視
- **日檢視**:單日任務清單
- **時間線**:甘特圖式顯示
#### 互動功能
- **拖拽調整**:直接拖動改變日期
- **快速編輯**:點選事項快速修改
- **顏色標示**:優先級和狀態色彩
- **提醒設定**:行事曆提醒整合
### 🏷️ 標籤管理
#### 標籤功能
- **自訂標籤**:建立個人化分類
- **顏色標示**:視覺化識別
- **快速篩選**:點選標籤快速篩選
- **統計分析**:標籤使用統計
#### 常用標籤建議
- 專案類:`#Project-A`, `#年度計劃`
- 部門類:`#IT`, `#HR`, `#Sales`
- 性質類:`#會議`, `#報告`, `#檢查`
- 狀態類:`#待確認`, `#進行中`, `#暫停`
### 🔍 進階搜尋
#### 搜尋語法
```
標題搜尋title:報告
描述搜尋desc:系統
人員搜尋user:張三
標籤搜尋tag:專案
狀態搜尋status:DOING
日期搜尋due:2024-01-15
```
#### 組合搜尋
```
複合條件title:報告 AND user:張三
排除條件title:會議 NOT status:DONE
日期範圍due:2024-01-01..2024-01-31
```
---
## 常見問題
### ❓ 登入相關
**Q: 忘記密碼怎麼辦?**
A: 系統使用公司 AD 帳號,請聯繫 IT 部門重設 Windows 密碼。
**Q: 帳號被鎖定無法登入?**
A: 通常是密碼輸入錯誤多次,請聯繫 IT 部門解鎖帳號。
**Q: 可以在家裡使用嗎?**
A: 需要連接公司 VPN 後才能存取內部系統。
### ❓ 功能使用
**Q: 為什麼找不到某個同事?**
A: 請確認:
1. 輸入正確的姓名或帳號
2. 該同事帳號未被停用
3. 有權限查看該同事資訊
**Q: 郵件通知沒有收到?**
A: 請檢查:
1. 垃圾信件匣
2. 通知設定是否開啟
3. 郵箱容量是否已滿
4. 公司郵件伺服器是否正常
**Q: Excel 匯入失敗?**
A: 常見原因:
1. 檔案格式不正確
2. 必填欄位為空
3. 日期格式錯誤
4. 人員帳號不存在
### ❓ 效能相關
**Q: 系統載入很慢?**
A: 建議:
1. 使用較新版本的瀏覽器
2. 清除瀏覽器快取
3. 檢查網路連線品質
4. 關閉不必要的分頁
**Q: 行動裝置使用不順?**
A: 建議:
1. 使用手機瀏覽器而非APP
2. 確保網路訊號穩定
3. 定期清理瀏覽器快取
### ❓ 資料安全
**Q: 資料會不會外洩?**
A: 系統安全措施:
1. 資料存放於公司內部伺服器
2. 使用 HTTPS 加密傳輸
3. AD 統一身份驗證
4. 定期備份和監控
**Q: 刪除的資料可以復原嗎?**
A:
1. 系統有30天的回收站功能
2. 重要資料有定期備份
3. 可聯繫管理員協助復原
---
## 🆘 技術支援
### 聯繫方式
- **IT服務台**:分機 XXX
- **Email**it-support@panjit.com.tw
- **內部聊天群**IT技術支援群組
### 支援時間
- **工作日**09:00 - 18:00
- **緊急問題**24小時 (電話支援)
- **系統維護時間**:每週日 02:00 - 04:00
### 提報問題時請提供
1. **問題描述**:詳細說明遇到的狀況
2. **操作步驟**:問題發生前的操作流程
3. **錯誤訊息**:如有錯誤訊息請完整記錄
4. **環境資訊**:使用的瀏覽器和作業系統
5. **螢幕截圖**:有助於快速診斷問題
---
**使用者手冊版本**1.0
**最後更新**2025年1月
**適用系統版本**PANJIT To-Do System v1.0
如有任何問題或建議,歡迎隨時聯繫 IT 部門。