4TH
This commit is contained in:
13
.gitignore
vendored
13
.gitignore
vendored
@@ -37,4 +37,17 @@ Thumbs.db
|
||||
# 忽略所有日誌檔案。
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# --- 環境設定檔 ---
|
||||
.env
|
||||
|
||||
# --- 測試相關 (Testing) ---
|
||||
# 忽略測試檔案
|
||||
test_*.py
|
||||
*_test.py
|
||||
tests/
|
||||
|
||||
# --- 開發者專用文件 (Developer Only) ---
|
||||
# 最佳實踐文件(包含敏感設定資訊)
|
||||
BEST_PRACTICES.md
|
||||
DEVELOPER_GUIDE.md
|
||||
|
@@ -12,8 +12,8 @@ cp .env.example .env
|
||||
|
||||
# 2. 編輯 .env 檔案 (重要!)
|
||||
# 設定以下關鍵參數:
|
||||
# - LDAP_SERVER=ldap://your-dc.panjit.com.tw
|
||||
# - LDAP_BIND_USER_DN=CN=service,DC=panjit,DC=com,DC=tw
|
||||
# - LDAP_SERVER=ldap://your-dc.company.com
|
||||
# - LDAP_BIND_USER_DN=CN=service,DC=company,DC=com
|
||||
# - LDAP_BIND_USER_PASSWORD=your_service_password
|
||||
|
||||
# 3. 啟動所有服務
|
||||
@@ -48,7 +48,7 @@ start-windows.bat
|
||||
- [ ] **LDAP連線**: 使用AD帳號測試登入
|
||||
|
||||
### 權限設定確認
|
||||
- [ ] **ymirliu@panjit.com.tw**: 已設定為管理員權限
|
||||
- [ ] **admin@company.com**: 已設定為管理員權限
|
||||
- [ ] **權限管理頁面**: 可透過選單訪問
|
||||
- [ ] **角色功能**: admin/editor/viewer 功能正常
|
||||
|
||||
@@ -99,7 +99,7 @@ docker-compose exec app python init_db.py
|
||||
1. **登入測試**
|
||||
```bash
|
||||
# 測試AD帳號登入
|
||||
用戶: ymirliu@panjit.com.tw (或 ymirliu)
|
||||
用戶: admin@company.com
|
||||
密碼: [AD密碼]
|
||||
```
|
||||
|
||||
@@ -174,7 +174,7 @@ docker-compose exec mysql mysql -u root -p -e "SHOW DATABASES;"
|
||||
```sql
|
||||
-- 直接在資料庫中設定管理員
|
||||
USE tempspec_db;
|
||||
UPDATE ts_user SET role='admin' WHERE username='ymirliu@panjit.com.tw';
|
||||
UPDATE ts_user SET role='admin' WHERE username='admin@company.com';
|
||||
```
|
||||
|
||||
### 快速重置
|
||||
@@ -247,4 +247,4 @@ Demo成功的標誌:
|
||||
|
||||
---
|
||||
|
||||
**祝您Demo順利!** 如有任何問題,請參考系統日誌或聯繫技術支援團隊。
|
||||
**祝您Demo順利!** 如有任何問題,請參考系統日誌。
|
@@ -687,4 +687,4 @@ curl -s http://localhost:5000/health | jq .
|
||||
|
||||
---
|
||||
|
||||
本部署指南涵蓋了大部分常見的部署場景。如果遇到特殊情況或需要客製化部署,請參考系統文檔或聯繫技術支援團隊。
|
||||
本部署指南涵蓋了大部分常見的部署場景。如果遇到特殊情況或需要客製化部署,請參考系統相關文檔。
|
297
README.md
297
README.md
@@ -21,6 +21,7 @@
|
||||
|
||||
### 智慧通知系統
|
||||
- **動態收件人選擇**:整合LDAP的即時用戶搜尋
|
||||
- **郵件記憶功能**:自動記憶並帶出之前使用的通知對象
|
||||
- **全流程通知**:啟用、展延、終止操作的自動郵件通知
|
||||
- **自動提醒**:3天與7天到期前的主動提醒郵件
|
||||
- **排程系統**:每日自動檢查即將到期的規範
|
||||
@@ -87,6 +88,12 @@ docker-compose up -d
|
||||
docker-compose exec app python init_db.py
|
||||
```
|
||||
|
||||
5. **資料庫遷移(如果需要)**
|
||||
```bash
|
||||
# 新增郵件功能欄位
|
||||
docker-compose exec app python migrate_add_email_column.py
|
||||
```
|
||||
|
||||
### 手動安裝
|
||||
|
||||
#### Windows 環境
|
||||
@@ -107,7 +114,12 @@ REM 編輯 .env 檔案
|
||||
python init_db.py
|
||||
```
|
||||
|
||||
4. **啟動 ONLYOFFICE Document Server**
|
||||
4. **資料庫遷移(如果需要)**
|
||||
```cmd
|
||||
python migrate_add_email_column.py
|
||||
```
|
||||
|
||||
5. **啟動 ONLYOFFICE Document Server**
|
||||
```cmd
|
||||
docker run -d -p 8080:80 --restart=always ^
|
||||
-e JWT_ENABLED=true ^
|
||||
@@ -115,7 +127,7 @@ docker run -d -p 8080:80 --restart=always ^
|
||||
onlyoffice/documentserver
|
||||
```
|
||||
|
||||
5. **啟動應用程式**
|
||||
6. **啟動應用程式**
|
||||
```cmd
|
||||
REM 開發環境
|
||||
python app.py
|
||||
@@ -143,7 +155,12 @@ cp .env.example .env
|
||||
python init_db.py
|
||||
```
|
||||
|
||||
4. **啟動 ONLYOFFICE Document Server**
|
||||
4. **資料庫遷移(如果需要)**
|
||||
```bash
|
||||
python migrate_add_email_column.py
|
||||
```
|
||||
|
||||
5. **啟動 ONLYOFFICE Document Server**
|
||||
```bash
|
||||
docker run -d -p 8080:80 --restart=always \
|
||||
-e JWT_ENABLED=true \
|
||||
@@ -151,7 +168,7 @@ docker run -d -p 8080:80 --restart=always \
|
||||
onlyoffice/documentserver
|
||||
```
|
||||
|
||||
5. **啟動應用程式**
|
||||
6. **啟動應用程式**
|
||||
```bash
|
||||
# 開發環境
|
||||
python app.py
|
||||
@@ -161,79 +178,6 @@ pip install gunicorn
|
||||
gunicorn -w 4 -b 0.0.0.0:5000 app:app
|
||||
```
|
||||
|
||||
### 生產環境部署
|
||||
|
||||
#### 使用 Nginx + Gunicorn (Linux)
|
||||
|
||||
1. **安裝 Gunicorn**
|
||||
```bash
|
||||
pip install gunicorn
|
||||
```
|
||||
|
||||
2. **建立 Gunicorn 服務檔案**
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/tempspec.service
|
||||
```
|
||||
|
||||
內容:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Temp Spec System
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/path/to/your/app
|
||||
Environment="PATH=/path/to/your/app/venv/bin"
|
||||
ExecStart=/path/to/your/app/venv/bin/gunicorn -w 4 -b 127.0.0.1:5000 app:app
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
3. **Nginx 設定**
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **啟動服務**
|
||||
```bash
|
||||
sudo systemctl enable tempspec
|
||||
sudo systemctl start tempspec
|
||||
```
|
||||
|
||||
#### Windows IIS 部署
|
||||
|
||||
1. **安裝 IIS 與 Python**
|
||||
2. **安裝 HttpPlatformHandler**
|
||||
3. **設定 Web.config**
|
||||
```xml
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="PythonHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
|
||||
</handlers>
|
||||
<httpPlatform processPath="C:\path\to\python.exe"
|
||||
arguments="app.py"
|
||||
startupTimeLimit="60"
|
||||
startupRetryCount="3">
|
||||
</httpPlatform>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
## ⚙️ 組態設定
|
||||
|
||||
### 環境變數 (.env)
|
||||
@@ -255,74 +199,29 @@ LDAP_BIND_USER_DN=CN=service,DC=company,DC=com
|
||||
LDAP_BIND_USER_PASSWORD=service_password
|
||||
LDAP_USER_LOGIN_ATTR=userPrincipalName
|
||||
|
||||
# SMTP 郵件設定
|
||||
SMTP_SERVER=smtp.company.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USE_TLS=True
|
||||
SMTP_SENDER_EMAIL=noreply@company.com
|
||||
SMTP_SENDER_PASSWORD=smtp_password
|
||||
# SMTP 郵件設定 (Port 25 無認證方式)
|
||||
SMTP_SERVER=mail.company.com
|
||||
SMTP_PORT=25
|
||||
SMTP_USE_TLS=false
|
||||
SMTP_USE_SSL=false
|
||||
SMTP_AUTH_REQUIRED=false
|
||||
SMTP_SENDER_EMAIL=temp-spec-system@company.com
|
||||
SMTP_SENDER_PASSWORD=
|
||||
|
||||
# ONLYOFFICE 設定
|
||||
ONLYOFFICE_URL=http://onlyoffice:8080
|
||||
ONLYOFFICE_JWT_SECRET=your_jwt_secret
|
||||
```
|
||||
|
||||
### 特殊注意事項
|
||||
### SMTP 配置說明
|
||||
|
||||
#### Windows 環境差異
|
||||
系統支援多種 SMTP 配置方式:
|
||||
|
||||
1. **排程服務限制**
|
||||
- APScheduler 在 Windows 上運行正常
|
||||
- 若使用 Celery,需要額外設定:
|
||||
```bash
|
||||
# Windows 環境需要使用 eventlet 或 solo 執行器
|
||||
celery -A app.celery worker --loglevel=info --pool=solo
|
||||
```
|
||||
- **Port 25(推薦)**:內部郵件伺服器,無需認證
|
||||
- **Port 587**:STARTTLS + 認證
|
||||
- **Port 465**:SSL + 認證
|
||||
|
||||
2. **路徑設定**
|
||||
```python
|
||||
# Windows 環境請使用絕對路徑或適當的路徑分隔符
|
||||
UPLOAD_FOLDER = r'C:\path\to\uploads'
|
||||
```
|
||||
|
||||
3. **服務安裝**
|
||||
```bash
|
||||
# 使用 NSSM 將 Python 應用程式安裝為 Windows 服務
|
||||
nssm install TempSpecSystem python.exe app.py
|
||||
```
|
||||
|
||||
#### Linux 環境最佳化
|
||||
|
||||
1. **系統服務設定**
|
||||
```bash
|
||||
# 設定系統服務自動啟動
|
||||
sudo systemctl enable tempspec.service
|
||||
```
|
||||
|
||||
2. **日誌管理**
|
||||
```bash
|
||||
# 使用 logrotate 管理日誌檔案
|
||||
sudo nano /etc/logrotate.d/tempspec
|
||||
```
|
||||
|
||||
3. **效能調校**
|
||||
```bash
|
||||
# Gunicorn 推薦設定
|
||||
gunicorn -w 4 -k gevent --worker-connections 1000 -b 0.0.0.0:5000 app:app
|
||||
```
|
||||
|
||||
## 🔐 安全性設定
|
||||
|
||||
### LDAP 整合
|
||||
- 支援 SSL/TLS 加密連線
|
||||
- 服務帳號權限最小化原則
|
||||
- 自動用戶同步與權限管控
|
||||
|
||||
### 資料保護
|
||||
- JWT Token 驗證
|
||||
- 檔案存取權限控制
|
||||
- SQL Injection 防護
|
||||
- XSS 攻擊防護
|
||||
詳細設定請參考 `SMTP_CONFIGURATION_UPDATE.md`
|
||||
|
||||
## 📚 使用說明
|
||||
|
||||
@@ -344,40 +243,34 @@ ONLYOFFICE_JWT_SECRET=your_jwt_secret
|
||||
UPDATE ts_user SET role='admin' WHERE username='user@domain.com';
|
||||
```
|
||||
|
||||
3. **程式設定**:修改 `routes/auth.py` 中的管理員帳號列表:
|
||||
```python
|
||||
# 將特定用戶設為管理員
|
||||
if user_info['username'].lower() == 'your_admin@domain.com':
|
||||
default_role = 'admin'
|
||||
```
|
||||
### 郵件通知功能
|
||||
|
||||
### 排程任務說明
|
||||
系統具備智慧郵件管理功能:
|
||||
|
||||
系統預設每天凌晨 2:00 執行到期檢查任務,可在 `app.py` 中調整:
|
||||
1. **規範生效時**:輸入通知郵件對象,系統自動記憶
|
||||
2. **規範終止時**:自動帶出生效時使用的郵件清單,可編輯後發送
|
||||
3. **規範展延時**:自動帶出郵件清單,修改後更新記錄
|
||||
|
||||
```python
|
||||
@scheduler.task('cron', id='check_expiring_specs_job', hour=2, minute=0)
|
||||
def scheduled_job():
|
||||
check_expiring_specs(app)
|
||||
```
|
||||
### 排程任務
|
||||
|
||||
### 自訂提醒天數
|
||||
系統預設每天凌晨 2:00 執行到期檢查任務:
|
||||
|
||||
在 `tasks.py` 中修改提醒時程:
|
||||
- 7天到期提醒
|
||||
- 3天到期提醒
|
||||
- 自動發送提醒郵件
|
||||
|
||||
```python
|
||||
seven_days_later = today + timedelta(days=7) # 7天前提醒
|
||||
three_days_later = today + timedelta(days=3) # 3天前提醒
|
||||
```
|
||||
## 🔐 安全性設定
|
||||
|
||||
### 預設收件人群組設定
|
||||
### LDAP 整合
|
||||
- 支援 SSL/TLS 加密連線
|
||||
- 服務帳號權限最小化原則
|
||||
- 自動用戶同步與權限管控
|
||||
|
||||
在 `tasks.py` 中設定自動提醒的收件人:
|
||||
|
||||
```python
|
||||
# 修改為實際的 AD 群組名稱
|
||||
default_recipients = get_ldap_group_members('TempSpec_Admins')
|
||||
```
|
||||
### 資料保護
|
||||
- JWT Token 驗證
|
||||
- 檔案存取權限控制
|
||||
- SQL Injection 防護
|
||||
- XSS 攻擊防護
|
||||
|
||||
## 🐛 疑難排解
|
||||
|
||||
@@ -395,19 +288,14 @@ default_recipients = get_ldap_group_members('TempSpec_Admins')
|
||||
|
||||
3. **郵件發送失敗**
|
||||
- 確認 SMTP 設定正確
|
||||
- 檢查郵件伺服器認證
|
||||
- 驗證防火牆規則 (通常是 25/587/465 port)
|
||||
- 檢查郵件伺服器認證設定
|
||||
- 驗證防火牆規則 (Port 25/587/465)
|
||||
|
||||
4. **排程任務未執行**
|
||||
- 檢查 APScheduler 初始化
|
||||
- 確認應用程式持續運行
|
||||
- 查看系統日誌
|
||||
|
||||
5. **檔案上傳失敗**
|
||||
- 檢查上傳目錄權限
|
||||
- 確認檔案大小限制設定
|
||||
- 驗證磁碟空間是否足夠
|
||||
|
||||
### 日誌查看
|
||||
|
||||
```bash
|
||||
@@ -421,40 +309,8 @@ tail -f logs/app.log
|
||||
Get-Content logs/app.log -Tail 10 -Wait
|
||||
```
|
||||
|
||||
### 效能監控
|
||||
|
||||
```bash
|
||||
# 監控資源使用
|
||||
htop
|
||||
docker stats
|
||||
|
||||
# 檢查資料庫效能
|
||||
SHOW PROCESSLIST;
|
||||
SHOW ENGINE INNODB STATUS;
|
||||
```
|
||||
|
||||
## 🤝 開發指南
|
||||
|
||||
### 開發環境設定
|
||||
|
||||
1. **虛擬環境建立**
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux
|
||||
venv\Scripts\activate # Windows
|
||||
```
|
||||
|
||||
2. **安裝開發依賴**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-dev.txt # 如果有開發專用依賴
|
||||
```
|
||||
|
||||
3. **資料庫遷移**
|
||||
```bash
|
||||
python init_db.py
|
||||
```
|
||||
|
||||
### 程式碼結構
|
||||
|
||||
```
|
||||
@@ -473,41 +329,38 @@ python init_db.py
|
||||
└── ldap_utils.py # LDAP 工具
|
||||
```
|
||||
|
||||
### 新增功能開發
|
||||
### 資料庫遷移
|
||||
|
||||
1. **建立新的路由模組**
|
||||
2. **新增對應的資料模型**
|
||||
3. **建立前端範本**
|
||||
4. **撰寫單元測試**
|
||||
當系統需要資料庫結構更新時:
|
||||
|
||||
```bash
|
||||
# 執行遷移腳本
|
||||
python migrate_add_email_column.py
|
||||
```
|
||||
|
||||
## 📄 授權條款
|
||||
|
||||
本專案採用 MIT 授權條款,詳見 [LICENSE](LICENSE) 檔案。
|
||||
本專案採用 MIT 授權條款。
|
||||
|
||||
## 🆕 版本歷程
|
||||
|
||||
### v3.0.0 (2024-01-XX)
|
||||
### v3.2.0 (最新版本)
|
||||
- 🆕 新增郵件通知記憶功能
|
||||
- 🆕 支援 Port 25 無認證 SMTP
|
||||
- ♻️ 優化郵件管理邏輯
|
||||
- 🗑️ 移除測試檔案和調試代碼
|
||||
|
||||
### v3.1.0
|
||||
- 🆕 新增 LDAP/AD 整合驗證
|
||||
- 🆕 整合 ONLYOFFICE 線上編輯器
|
||||
- 🆕 整合 ONLYOFFICE 線上編輯器
|
||||
- 🆕 實作智慧通知系統
|
||||
- 🆕 新增自動排程提醒功能
|
||||
- 🆕 支援 Docker 容器化部署
|
||||
|
||||
### v3.0.0
|
||||
- ♻️ 重構權限管理系統
|
||||
- 🗑️ 移除本地帳號管理功能
|
||||
|
||||
### v2.x.x
|
||||
- Toast UI Editor 整合
|
||||
- 基本文件管理功能
|
||||
- 本地帳號系統
|
||||
|
||||
## 📞 技術支援
|
||||
|
||||
如有問題或建議,請透過以下方式聯繫:
|
||||
|
||||
- 📧 Email: support@company.com
|
||||
- 📋 Issue Tracker: GitHub Issues
|
||||
- 📖 文件wiki: GitHub Wiki
|
||||
|
||||
---
|
||||
|
||||
**暫時規範管理系統 V3** - 讓企業文件管理更智慧、更高效!
|
331
USER_MANUAL.md
331
USER_MANUAL.md
@@ -18,10 +18,12 @@
|
||||
|
||||
暫時規範管理系統 V3 是一個集中化平台,用於管理、追蹤和存檔所有暫時性的工程規範。它涵蓋了從草擬、線上編輯、簽核、生效到最終歸檔的完整生命週期。
|
||||
|
||||
### 🚀 V3 版本新特色
|
||||
### 🚀 V3.2 版本新特色
|
||||
|
||||
- **LDAP/AD 整合**:使用企業Active Directory帳號登入
|
||||
- **智慧通知系統**:動態收件人選擇與自動提醒
|
||||
- **智慧郵件記憶**:自動記憶並帶出之前使用的通知對象
|
||||
- **彈性郵件編輯**:可編輯通知名單並更新記錄
|
||||
- **多種SMTP支援**:支援Port 25無認證及其他認證方式
|
||||
- **自動排程提醒**:系統主動發送到期提醒郵件
|
||||
- **增強的編輯體驗**:ONLYOFFICE文件協作編輯
|
||||
|
||||
@@ -31,7 +33,7 @@
|
||||
|
||||
### 2.1 LDAP 登入
|
||||
|
||||
🆕 **V3 新功能**:系統現在使用企業 Active Directory 進行單一登入。
|
||||
系統使用企業 Active Directory 進行單一登入。
|
||||
|
||||
**🚨 重要登入規範**:
|
||||
|
||||
@@ -48,152 +50,164 @@
|
||||
|
||||
> **注意**:
|
||||
> - 首次登入的用戶預設為 `Viewer` 權限
|
||||
> - 如需提升權限請聯繫系統管理員
|
||||
> - 需要聯繫系統管理員提升權限
|
||||
|
||||
### 2.2 主畫面功能
|
||||
### 2.2 主畫面導覽
|
||||
|
||||
登入後進入暫時規範總表,包含以下區域:
|
||||
登入後會看到暫時規範列表,包含:
|
||||
|
||||
- **🔍 搜尋與篩選區**:根據編號、主題或狀態快速查找
|
||||
- **📊 狀態統計**:顯示各狀態規範的數量概覽
|
||||
- **📋 規範列表**:詳細顯示所有規範資訊
|
||||
- **⚡ 快速操作**:根據權限和規範狀態提供操作按鈕
|
||||
|
||||
### 2.3 狀態指示說明
|
||||
|
||||
| 狀態 | 圖示 | 說明 |
|
||||
|------|------|------|
|
||||
| 待生效 | 🟡 | 草稿完成,待管理員啟用 |
|
||||
| 已生效 | 🟢 | 正在生效中的規範 |
|
||||
| 已過期 | 🔴 | 已自動過期的規範 |
|
||||
| 已終止 | ⚫ | 提早終止的規範 |
|
||||
- **規範編號**:系統自動產生(PE+民國年+月份+序號)
|
||||
- **主題**:規範標題
|
||||
- **申請人**:規範申請者
|
||||
- **狀態**:pending_approval(待生效)/active(已生效)/expired(已過期)/terminated(已終止)
|
||||
- **時間範圍**:生效日期至結束日期
|
||||
- **操作按鈕**:依權限顯示不同功能
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心操作流程
|
||||
|
||||
### 3.1 完整工作流程
|
||||
### 3.1 建立新規範(Editor/Admin 權限)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Editor建立草稿] --> B[ONLYOFFICE線上編輯]
|
||||
B --> C[下載Word文件]
|
||||
C --> D[線下簽核流程]
|
||||
D --> E[Admin上傳PDF啟用]
|
||||
E --> F[🆕選擇通知對象]
|
||||
F --> G[規範正式生效]
|
||||
G --> H[🆕自動到期提醒]
|
||||
```
|
||||
1. 點擊「**新增規範**」按鈕
|
||||
2. 填寫規範資訊:
|
||||
- **主題**:規範標題
|
||||
- **申請人**:申請者姓名
|
||||
- **申請人電話**:聯絡電話
|
||||
- **相關資訊**:包裝、批號、設備類型等
|
||||
|
||||
### 3.2 建立新的暫時規範 (Editor / Admin)
|
||||
3. **選擇適用站別**:
|
||||
- Probing、Dicing、Die bond、Wire bond 等
|
||||
- 可多選
|
||||
|
||||
1. **建立草稿**
|
||||
- 點擊 **[+ 暫時規範建立]** 按鈕
|
||||
- 填寫基本資料:主題、申請人、站別等
|
||||
- 選擇適用的 TCCS 等級和 4M 類別
|
||||
- 點擊 **[建立並開始編輯]**
|
||||
4. **TCCS等級選擇**:
|
||||
- L1-L4 四個等級
|
||||
- 單選
|
||||
|
||||
2. **線上編輯**
|
||||
- 系統自動開啟 ONLYOFFICE 編輯器
|
||||
- 文件已預填初始資料
|
||||
- 支援多人協作編輯
|
||||
- 所有變更自動儲存
|
||||
5. **4M選擇**:
|
||||
- Man、Machine、Material、Method、Environment
|
||||
- 單選
|
||||
|
||||
3. **完成草稿**
|
||||
- 編輯完成後可直接關閉編輯器
|
||||
- 或點擊 **[完成編輯]** 返回總表
|
||||
6. 點擊「**建立**」完成草稿建立
|
||||
|
||||
### 3.3 啟用暫時規範 (僅限 Admin)
|
||||
### 3.2 編輯規範內容(Editor/Admin 權限)
|
||||
|
||||
🆕 **新增智慧通知功能**
|
||||
**🆕 ONLYOFFICE 線上編輯**:
|
||||
|
||||
1. **開始啟用流程**
|
||||
- 找到狀態為「待生效」的規範
|
||||
- 點擊 **啟用圖示 (✅)**
|
||||
1. 在規範列表點擊「**編輯**」按鈕
|
||||
2. 系統開啟 ONLYOFFICE 編輯器
|
||||
3. 進行文件編輯、格式調整
|
||||
4. 使用 **Ctrl+S** 定期儲存
|
||||
5. 編輯完成後關閉編輯器視窗
|
||||
|
||||
2. **上傳簽核文件**
|
||||
- 上傳已簽核完成的 PDF 檔案
|
||||
- 系統自動驗證檔案格式
|
||||
**編輯器功能**:
|
||||
- 全功能 Word 文件編輯
|
||||
- 即時自動儲存
|
||||
- 支援圖片、表格插入
|
||||
- 格式化工具列
|
||||
|
||||
3. **🆕 選擇通知對象**
|
||||
- 在「郵件通知對象」欄位輸入姓名或Email
|
||||
- 系統即時搜尋 LDAP 用戶
|
||||
- 支援多人選擇
|
||||
- 可選擇不發送通知
|
||||
### 3.3 啟用規範(Admin 權限)
|
||||
|
||||
4. **確認啟用**
|
||||
- 點擊 **[上傳並啟用]**
|
||||
- 系統發送啟用通知郵件
|
||||
- 規範狀態變更為「已生效」
|
||||
將規範從「待生效」變更為「已生效」狀態:
|
||||
|
||||
### 3.4 展延暫時規範 (Editor / Admin)
|
||||
1. 點擊「**啟用**」按鈕
|
||||
2. **上傳已簽核檔案**:選擇已簽核的PDF檔案
|
||||
3. **設定通知對象**:
|
||||
- 在搜尋框輸入姓名或Email(至少2個字元)
|
||||
- 從下拉清單選擇收件者
|
||||
- 支援AD群組搜尋(格式:`group:群組名稱`)
|
||||
- 可選擇多位收件者
|
||||
|
||||
🆕 **新增智慧通知功能**
|
||||
4. 點擊「**確認啟用**」
|
||||
5. 系統自動:
|
||||
- 更新規範狀態
|
||||
- **記憶通知對象**供後續使用
|
||||
- 發送啟用通知郵件
|
||||
|
||||
1. **開始展延**
|
||||
- 點擊 **展延圖示 (📅+)**
|
||||
- 選擇新的結束日期
|
||||
### 3.4 展延規範(Editor/Admin 權限)
|
||||
|
||||
2. **上傳佐證文件**
|
||||
- 必須上傳新的佐證文件 (PDF格式)
|
||||
延長已生效規範的結束日期:
|
||||
|
||||
3. **🆕 通知對象選擇**
|
||||
- 選擇需要通知的相關人員
|
||||
- 使用動態搜尋功能選擇收件人
|
||||
1. 點擊「**展延**」按鈕
|
||||
2. **設定新結束日期**:選擇展延後的日期
|
||||
3. **上傳佐證檔案**:提供展延理由相關文件(PDF格式)
|
||||
4. **🆕 智慧通知設定**:
|
||||
- 系統自動帶出之前啟用時使用的通知對象
|
||||
- 可直接使用或進行編輯
|
||||
- 修改後的名單會更新到系統記錄中
|
||||
|
||||
4. **確認展延**
|
||||
- 點擊 **[確認展延]**
|
||||
- 系統發送展延通知郵件
|
||||
5. 點擊「**確認展延**」
|
||||
6. 系統自動發送展延通知郵件
|
||||
|
||||
### 3.5 終止暫時規範 (Editor / Admin)
|
||||
### 3.5 終止規範(Editor/Admin 權限)
|
||||
|
||||
🆕 **新增智慧通知功能**
|
||||
提早結束規範:
|
||||
|
||||
1. **開始終止**
|
||||
- 點擊 **終止圖示 (❌)**
|
||||
- 填寫提早結束原因
|
||||
1. 點擊「**終止**」按鈕
|
||||
2. **填寫終止原因**:說明提早結束的理由
|
||||
3. **🆕 智慧通知設定**:
|
||||
- 系統自動帶出之前啟用時使用的通知對象
|
||||
- 顯示提示「以下為生效時設定的通知對象」
|
||||
- 可直接使用或進行編輯
|
||||
|
||||
2. **🆕 通知設定**
|
||||
- 選擇需要通知終止訊息的人員
|
||||
|
||||
3. **確認終止**
|
||||
- 點擊 **[確認終止]**
|
||||
- 系統發送終止通知郵件
|
||||
- 規範狀態變為「已終止」
|
||||
4. 點擊「**確認終止**」
|
||||
5. 系統自動:
|
||||
- 更新結束日期為今日
|
||||
- 發送終止通知郵件
|
||||
|
||||
---
|
||||
|
||||
## 4. 智慧通知系統
|
||||
|
||||
🆕 **V3 全新功能**
|
||||
### 4.1 🆕 郵件記憶功能
|
||||
|
||||
### 4.1 動態收件人選擇
|
||||
**V3.2 新增功能**:系統現在具備智慧郵件管理能力
|
||||
|
||||
所有主要操作(啟用、展延、終止)都支援智慧通知:
|
||||
**運作機制**:
|
||||
1. **規範啟用時**:輸入通知郵件對象,系統自動記憶
|
||||
2. **規範終止時**:自動帶出啟用時的郵件清單,可編輯後發送
|
||||
3. **規範展延時**:自動帶出郵件清單,修改後會更新記錄
|
||||
|
||||
- **即時搜尋**:輸入姓名或Email即時搜尋AD用戶
|
||||
- **多人選擇**:支援選擇多位收件人
|
||||
- **自動完成**:顯示完整姓名和Email資訊
|
||||
- **移除功能**:可隨時移除已選擇的收件人
|
||||
**操作說明**:
|
||||
- 系統會顯示「以下為生效時設定的通知對象」提示
|
||||
- 可以直接使用預設的郵件清單
|
||||
- 也可以修改郵件清單後再發送
|
||||
- 展延時修改的名單會成為新的預設通知對象
|
||||
|
||||
### 4.2 通知郵件內容
|
||||
### 4.2 動態收件人選擇
|
||||
|
||||
系統會根據操作類型自動發送相應的通知郵件:
|
||||
**搜尋功能**:
|
||||
- 輸入至少 **2個字元** 開始搜尋
|
||||
- 支援姓名或Email模糊搜尋
|
||||
- 即時顯示搜尋結果
|
||||
|
||||
- **啟用通知**:包含規範編號、主題、生效/結束日期
|
||||
- **展延通知**:包含新的結束日期和展延原因
|
||||
- **終止通知**:包含終止原因和終止日期
|
||||
**選擇方式**:
|
||||
- **個人用戶**:直接選擇用戶
|
||||
- **AD群組**:輸入 `group:群組名稱` 選擇整個群組
|
||||
- **多重選擇**:可同時選擇多位收件者
|
||||
|
||||
### 4.3 🆕 自動到期提醒
|
||||
**群組搜尋**:
|
||||
- 格式:`group:TempSpec_Admins`
|
||||
- 系統會自動展開群組成員
|
||||
- 發送時會寄給所有群組成員
|
||||
|
||||
系統每天自動檢查即將到期的規範:
|
||||
### 4.3 通知類型
|
||||
|
||||
- **7天前提醒**:首次到期預警
|
||||
- **3天前提醒**:最終到期提醒
|
||||
- **自動發送**:無需人工干預
|
||||
- **群組通知**:發送給預設管理群組
|
||||
**手動通知**(操作觸發):
|
||||
- 規範啟用通知
|
||||
- 規範展延通知
|
||||
- 規範終止通知
|
||||
|
||||
> **管理員設定**:可在 `tasks.py` 中修改提醒天數和收件人群組
|
||||
**🆕 自動提醒**(系統排程):
|
||||
- **7天到期提醒**:在規範到期前7天自動發送
|
||||
- **3天到期提醒**:在規範到期前3天自動發送
|
||||
- **發送時間**:每天凌晨2:00檢查並發送
|
||||
|
||||
**郵件內容**:
|
||||
- HTML格式美化顯示
|
||||
- 包含規範編號、標題、申請人
|
||||
- 明確標示生效/結束日期
|
||||
- 提供系統連結
|
||||
|
||||
---
|
||||
|
||||
@@ -230,12 +244,12 @@ graph TD
|
||||
- 操作類型(建立/啟用/展延/終止)
|
||||
- 詳細說明
|
||||
|
||||
### 5.4 🆕 即將到期警示
|
||||
### 5.4 即將到期警示
|
||||
|
||||
在規範列表中會特別標示即將到期的規範:
|
||||
|
||||
- **🟡 橙色標示**:7天內到期
|
||||
- **🔴 紅色標示**:3天內到期
|
||||
- **🔴 紅色標示**:3天內到期
|
||||
- **閃爍動畫**:今日到期
|
||||
|
||||
---
|
||||
@@ -250,17 +264,24 @@ graph TD
|
||||
| **Editor** | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
|
||||
| **Admin** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
### 6.2 🆕 LDAP 權限管理
|
||||
### 6.2 權限說明
|
||||
|
||||
- **自動用戶創建**:AD用戶首次登入自動建立帳號
|
||||
- **預設權限**:新用戶預設為 `Viewer` 權限
|
||||
- **權限提升**:需要管理員手動調整資料庫或修改程式碼
|
||||
**Viewer(檢視者)**:
|
||||
- 檢視所有規範內容
|
||||
- 下載PDF檔案
|
||||
- 檢視歷史紀錄
|
||||
|
||||
**管理員手動提升權限**:
|
||||
```sql
|
||||
-- 使用完整UPN格式帳號
|
||||
UPDATE ts_user SET role='admin' WHERE username='user@domain.com';
|
||||
```
|
||||
**Editor(編輯者)**:
|
||||
- 建立新規範草稿
|
||||
- 編輯規範內容
|
||||
- 展延和終止規範
|
||||
- 下載Word和PDF檔案
|
||||
|
||||
**Admin(管理員)**:
|
||||
- 所有Editor權限
|
||||
- 啟用規範(上傳簽核檔案)
|
||||
- 刪除規範
|
||||
- 系統管理功能
|
||||
|
||||
---
|
||||
|
||||
@@ -268,40 +289,39 @@ UPDATE ts_user SET role='admin' WHERE username='user@domain.com';
|
||||
|
||||
### 7.1 登入相關
|
||||
|
||||
**Q: 無法使用AD帳號登入?**
|
||||
A: 請確認:
|
||||
1. **必須使用完整UPN格式**:例如 user@domain.com(不支援縮略帳號如 user)
|
||||
2. 密碼正確
|
||||
3. 帳號未被鎖定
|
||||
4. 聯繫IT部門確認LDAP連線狀態
|
||||
**Q: 忘記帳號格式?**
|
||||
A: 必須使用完整的 `user@domain.com` 格式,不能只輸入 `user`
|
||||
|
||||
**Q: 忘記密碼怎麼辦?**
|
||||
A: 系統使用AD驗證,請透過企業標準流程重設AD密碼。
|
||||
**Q: 無法登入?**
|
||||
A: 請確認:
|
||||
1. 帳號格式正確(包含@domain.com)
|
||||
2. 密碼正確
|
||||
3. AD帳號未被鎖定
|
||||
4. 網路連線正常
|
||||
|
||||
### 7.2 權限相關
|
||||
|
||||
**Q: 為什麼我看不到建立規範按鈕?**
|
||||
A: 您的權限可能為 `Viewer`,請聯繫管理員提升權限至 `Editor`。
|
||||
**Q: 無法建立規範?**
|
||||
A: 請確認您的權限等級,Viewer無法建立規範,需要Editor以上權限。
|
||||
|
||||
**Q: 為什麼我無法啟用規範?**
|
||||
A: 啟用功能僅限 `Admin` 權限,請聯繫系統管理員操作。
|
||||
**Q: 無法啟用規範?**
|
||||
A: 啟用功能需要Admin權限,請聯繫系統管理員。
|
||||
|
||||
### 7.3 編輯器相關
|
||||
### 7.3 編輯相關
|
||||
|
||||
**Q: ONLYOFFICE編輯器無法載入?**
|
||||
A: 請檢查:
|
||||
1. 瀏覽器是否允許彈出視窗
|
||||
2. 網路連線是否正常
|
||||
3. 是否安裝最新版瀏覽器
|
||||
4. 聯繫IT確認Document Server狀態
|
||||
A: 請確認:
|
||||
1. 瀏覽器支援(建議Chrome/Edge)
|
||||
2. 網路連線穩定
|
||||
3. 彈出視窗未被阻擋
|
||||
|
||||
**Q: 編輯內容未儲存?**
|
||||
A: ONLYOFFICE有自動儲存功能,但請確認:
|
||||
A: 建議:
|
||||
1. 編輯期間保持網路連線
|
||||
2. 避免同時多人編輯同一文件
|
||||
3. 定期手動儲存 (Ctrl+S)
|
||||
|
||||
### 7.4 🆕 通知相關
|
||||
### 7.4 通知相關
|
||||
|
||||
**Q: 搜尋不到AD用戶?**
|
||||
A: 請確認:
|
||||
@@ -314,11 +334,16 @@ A: 請檢查:
|
||||
1. Email地址是否正確
|
||||
2. 垃圾郵件資料夾
|
||||
3. 公司郵件伺服器設定
|
||||
4. 聯繫IT確認SMTP設定
|
||||
|
||||
**Q: 自動提醒郵件何時發送?**
|
||||
A: 系統每天凌晨2:00自動檢查並發送提醒,分別在到期前7天和3天發送。
|
||||
|
||||
**🆕 Q: 郵件通知對象會自動記憶嗎?**
|
||||
A: 是的,系統會記憶啟用時設定的通知對象:
|
||||
- 終止規範時會自動帶出之前的郵件清單
|
||||
- 展延規範時也會自動帶出,修改後會更新記錄
|
||||
- 您可以直接使用或編輯後再發送
|
||||
|
||||
### 7.5 檔案相關
|
||||
|
||||
**Q: 可以上傳Word檔案來啟用規範嗎?**
|
||||
@@ -342,23 +367,27 @@ A: 可能原因:
|
||||
|
||||
---
|
||||
|
||||
## 🆘 技術支援
|
||||
|
||||
如遇到本手冊未涵蓋的問題,請透過以下方式聯繫:
|
||||
|
||||
- **📧 系統管理員**: [admin@company.com](mailto:admin@company.com)
|
||||
- **📞 IT支援專線**: 分機 2345
|
||||
- **💬 企業即時通**: #temp-spec-support
|
||||
|
||||
---
|
||||
|
||||
## 📝 版本資訊
|
||||
|
||||
- **文件版本**: V3.0.0
|
||||
- **最後更新**: 2024年1月
|
||||
- **適用系統**: 暫時規範管理系統 V3
|
||||
- **文件版本**: V3.2.0
|
||||
- **最後更新**: 2025年1月
|
||||
- **適用系統**: 暫時規範管理系統 V3.2
|
||||
|
||||
### 版本更新記錄
|
||||
|
||||
**V3.2.0**:
|
||||
- 新增郵件通知記憶功能
|
||||
- 支援Port 25無認證SMTP
|
||||
- 優化郵件管理邏輯
|
||||
- 更新操作說明
|
||||
|
||||
**V3.1.0**:
|
||||
- 新增LDAP/AD整合認證
|
||||
- 整合ONLYOFFICE線上編輯器
|
||||
- 實作智慧通知系統
|
||||
- 新增自動排程提醒功能
|
||||
|
||||
---
|
||||
|
||||
**感謝您使用暫時規範管理系統 V3!**
|
||||
希望這個操作手冊能幫助您更有效地使用系統功能。如有任何建議或回饋,歡迎與我們聯繫。
|
||||
希望這個操作手冊能幫助您更有效地使用系統功能。
|
72
test_api.py
72
test_api.py
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
測試 LDAP API 端點功能
|
||||
"""
|
||||
import requests
|
||||
import json
|
||||
|
||||
def test_api_search():
|
||||
"""測試 API 搜尋功能"""
|
||||
print("=== 測試 LDAP API 搜尋功能 ===")
|
||||
|
||||
# 測試不同的搜尋詞
|
||||
test_terms = ["liu", "劉", "PE", "管理", "admin"]
|
||||
|
||||
base_url = "http://127.0.0.1:5000"
|
||||
|
||||
# 先登入獲取 session cookie
|
||||
session = requests.Session()
|
||||
|
||||
print("正在登入系統...")
|
||||
login_data = {
|
||||
'username': 'ymirliu@panjit.com.tw',
|
||||
'password': input("請輸入 ymirliu@panjit.com.tw 的密碼: ")
|
||||
}
|
||||
|
||||
# 嘗試登入
|
||||
login_response = session.post(f"{base_url}/login", data=login_data)
|
||||
|
||||
if login_response.status_code == 200 and "總表檢視" in login_response.text:
|
||||
print("✅ 登入成功")
|
||||
|
||||
for term in test_terms:
|
||||
print(f"\n🔍 測試搜尋: '{term}'")
|
||||
print("-" * 40)
|
||||
|
||||
api_url = f"{base_url}/api/ldap-search"
|
||||
params = {'q': term}
|
||||
|
||||
try:
|
||||
response = session.get(api_url, params=params)
|
||||
print(f"HTTP 狀態: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
data = response.json()
|
||||
print(f"找到 {len(data)} 個結果:")
|
||||
|
||||
for i, result in enumerate(data, 1):
|
||||
print(f" {i}. {result.get('text', 'N/A')}")
|
||||
print(f" 值: {result.get('value', 'N/A')}")
|
||||
print(f" 類型: {result.get('type', 'N/A')}")
|
||||
|
||||
except json.JSONDecodeError:
|
||||
print("❌ 回應不是有效的 JSON")
|
||||
print(f"回應內容: {response.text[:200]}")
|
||||
else:
|
||||
print(f"❌ API 請求失敗: {response.status_code}")
|
||||
print(f"回應: {response.text[:200]}")
|
||||
|
||||
except requests.RequestException as e:
|
||||
print(f"❌ 請求錯誤: {e}")
|
||||
else:
|
||||
print("❌ 登入失敗")
|
||||
print(f"HTTP 狀態: {login_response.status_code}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
test_api_search()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n測試已中斷")
|
||||
except Exception as e:
|
||||
print(f"\n測試發生錯誤: {e}")
|
116
test_ldap.py
116
test_ldap.py
@@ -1,116 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
簡單的 LDAP 連線測試腳本
|
||||
用於驗證 LDAP 設定是否正確
|
||||
"""
|
||||
|
||||
from ldap3 import Server, Connection, ALL
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# 載入環境變數
|
||||
load_dotenv()
|
||||
|
||||
def test_ldap_connection():
|
||||
"""測試 LDAP 伺服器連線"""
|
||||
print("=== LDAP 連線測試 ===")
|
||||
|
||||
# 讀取設定
|
||||
ldap_server = os.getenv('LDAP_SERVER')
|
||||
ldap_port = int(os.getenv('LDAP_PORT', 389))
|
||||
use_ssl = os.getenv('LDAP_USE_SSL', 'false').lower() in ['true', '1', 't']
|
||||
bind_dn = os.getenv('LDAP_BIND_USER_DN')
|
||||
bind_password = os.getenv('LDAP_BIND_USER_PASSWORD')
|
||||
search_base = os.getenv('LDAP_SEARCH_BASE')
|
||||
|
||||
print(f"LDAP 伺服器: {ldap_server}")
|
||||
print(f"LDAP 連接埠: {ldap_port}")
|
||||
print(f"使用 SSL: {use_ssl}")
|
||||
print(f"搜尋基底: {search_base}")
|
||||
print(f"服務帳號 DN: {bind_dn}")
|
||||
|
||||
try:
|
||||
# 建立伺服器連線
|
||||
server = Server(ldap_server, port=ldap_port, use_ssl=use_ssl, get_info=ALL)
|
||||
print(f"✅ LDAP 伺服器物件建立成功")
|
||||
|
||||
# 測試服務帳號連線
|
||||
print("正在測試服務帳號連線...")
|
||||
conn = Connection(server, user=bind_dn, password=bind_password, auto_bind=True)
|
||||
|
||||
if conn.bound:
|
||||
print("✅ 服務帳號連線成功!")
|
||||
|
||||
# 測試搜尋功能
|
||||
print("正在測試 LDAP 搜尋功能...")
|
||||
search_filter = "(objectClass=user)"
|
||||
conn.search(search_base, search_filter, attributes=['dn'], size_limit=5)
|
||||
|
||||
if conn.entries:
|
||||
print(f"✅ LDAP 搜尋成功,找到 {len(conn.entries)} 個條目")
|
||||
for entry in conn.entries[:3]:
|
||||
print(f" - {entry.entry_dn}")
|
||||
else:
|
||||
print("⚠️ LDAP 搜尋沒有找到任何條目")
|
||||
|
||||
conn.unbind()
|
||||
else:
|
||||
print("❌ 服務帳號連線失敗")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ LDAP 連線錯誤: {e}")
|
||||
return False
|
||||
|
||||
print("=== LDAP 連線測試完成 ===")
|
||||
return True
|
||||
|
||||
def test_user_authentication():
|
||||
"""測試使用者認證 (需要手動輸入測試帳號)"""
|
||||
print("\n=== 使用者認證測試 ===")
|
||||
|
||||
test_user = input("請輸入測試用帳號 (完整UPN格式,如 user@domain.com): ").strip()
|
||||
if not test_user or '@' not in test_user:
|
||||
print("❌ 帳號格式不正確")
|
||||
return False
|
||||
|
||||
test_password = input("請輸入測試密碼: ").strip()
|
||||
if not test_password:
|
||||
print("❌ 密碼不可為空")
|
||||
return False
|
||||
|
||||
# 讀取設定
|
||||
ldap_server = os.getenv('LDAP_SERVER')
|
||||
ldap_port = int(os.getenv('LDAP_PORT', 389))
|
||||
use_ssl = os.getenv('LDAP_USE_SSL', 'false').lower() in ['true', '1', 't']
|
||||
|
||||
try:
|
||||
server = Server(ldap_server, port=ldap_port, use_ssl=use_ssl, get_info=ALL)
|
||||
|
||||
print(f"正在驗證 {test_user}...")
|
||||
conn = Connection(server, user=test_user, password=test_password, auto_bind=True)
|
||||
|
||||
if conn.bound:
|
||||
print("✅ 使用者認證成功!")
|
||||
conn.unbind()
|
||||
return True
|
||||
else:
|
||||
print("❌ 使用者認證失敗 - 帳號或密碼錯誤")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 認證過程發生錯誤: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("LDAP 測試工具")
|
||||
print("此工具用於測試 LDAP 連線和認證功能\n")
|
||||
|
||||
# 測試 LDAP 連線
|
||||
if test_ldap_connection():
|
||||
# 如果連線測試通過,可以選擇測試使用者認證
|
||||
choice = input("\n是否要測試使用者認證? (y/N): ").strip().lower()
|
||||
if choice == 'y':
|
||||
test_user_authentication()
|
||||
|
||||
input("\n按 Enter 鍵結束...")
|
@@ -1,113 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
測試 LDAP 搜尋功能的獨立腳本
|
||||
用於偵錯郵件通知對象搜尋問題
|
||||
"""
|
||||
|
||||
from ldap_utils import search_ldap_principals, search_ldap_groups
|
||||
from app import app
|
||||
import sys
|
||||
|
||||
def test_user_search():
|
||||
"""測試使用者搜尋功能"""
|
||||
print("=== 測試使用者搜尋功能 ===")
|
||||
|
||||
test_terms = ["劉", "liu", "管理", "admin", "工程"]
|
||||
|
||||
for term in test_terms:
|
||||
print(f"\n搜尋詞: '{term}'")
|
||||
print("-" * 40)
|
||||
|
||||
try:
|
||||
results = search_ldap_principals(term, limit=10)
|
||||
print(f"找到 {len(results)} 個結果:")
|
||||
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"{i}. {result['name']} ({result['email']})")
|
||||
|
||||
except Exception as e:
|
||||
print(f"搜尋失敗: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def test_group_search():
|
||||
"""測試群組搜尋功能"""
|
||||
print("\n=== 測試群組搜尋功能 ===")
|
||||
|
||||
test_terms = ["管理", "工程", "admin", "group"]
|
||||
|
||||
for term in test_terms:
|
||||
print(f"\n搜尋詞: '{term}'")
|
||||
print("-" * 40)
|
||||
|
||||
try:
|
||||
results = search_ldap_groups(term, limit=10)
|
||||
print(f"找到 {len(results)} 個群組:")
|
||||
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"{i}. {result['name']} (成員數: {result['member_count']})")
|
||||
|
||||
except Exception as e:
|
||||
print(f"群組搜尋失敗: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def test_interactive_search():
|
||||
"""互動式搜尋測試"""
|
||||
print("\n=== 互動式搜尋測試 ===")
|
||||
|
||||
while True:
|
||||
search_term = input("\n請輸入搜尋詞 (或輸入 'quit' 結束): ").strip()
|
||||
|
||||
if search_term.lower() == 'quit':
|
||||
break
|
||||
|
||||
if not search_term:
|
||||
continue
|
||||
|
||||
print(f"\n搜尋 '{search_term}'...")
|
||||
|
||||
# 搜尋使用者
|
||||
try:
|
||||
user_results = search_ldap_principals(search_term, limit=10)
|
||||
print(f"\n👤 使用者結果 ({len(user_results)}):")
|
||||
for i, result in enumerate(user_results, 1):
|
||||
print(f" {i}. {result['name']} ({result['email']})")
|
||||
except Exception as e:
|
||||
print(f"使用者搜尋失敗: {e}")
|
||||
|
||||
# 搜尋群組
|
||||
try:
|
||||
group_results = search_ldap_groups(search_term, limit=5)
|
||||
print(f"\n👥 群組結果 ({len(group_results)}):")
|
||||
for i, result in enumerate(group_results, 1):
|
||||
print(f" {i}. {result['name']} (成員: {result['member_count']})")
|
||||
except Exception as e:
|
||||
print(f"群組搜尋失敗: {e}")
|
||||
|
||||
def main():
|
||||
"""主測試函式"""
|
||||
print("LDAP 搜尋功能測試工具")
|
||||
print("=" * 50)
|
||||
|
||||
with app.app_context():
|
||||
# 測試預設搜尋詞
|
||||
test_user_search()
|
||||
test_group_search()
|
||||
|
||||
# 互動式測試
|
||||
choice = input("\n是否要進行互動式搜尋測試? (y/N): ").strip().lower()
|
||||
if choice == 'y':
|
||||
test_interactive_search()
|
||||
|
||||
print("\n測試完成!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n測試已中斷")
|
||||
except Exception as e:
|
||||
print(f"\n測試發生錯誤: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
@@ -1,126 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
測試組織架構搜尋功能的獨立腳本
|
||||
根據您提供的組織架構圖進行測試
|
||||
"""
|
||||
|
||||
from ldap_utils import search_ldap_groups
|
||||
from app import app
|
||||
|
||||
def test_org_units():
|
||||
"""測試組織單位搜尋"""
|
||||
print("=== 測試組織單位搜尋 ===")
|
||||
|
||||
# 根據您的組織架構圖測試這些關鍵字
|
||||
test_terms = [
|
||||
"PANJIT", # 主要組織
|
||||
"Audit Office", # 稽核室
|
||||
"Fab bu", # 晶圓事業部
|
||||
"CFPU", # 客戶產品事業部
|
||||
"GMO", # 總經理室
|
||||
"RBU", # 新創事業處
|
||||
"kM_ESP", # 知識管理
|
||||
"SBG", # 特殊應用事業群
|
||||
"AUBU", # 車載事業處
|
||||
"IQBU", # 檢測事業處
|
||||
"MBU1", # 行銷事業處1
|
||||
"AssEng", # 製程工程
|
||||
"scottlee", # 個人帳號
|
||||
"staceychu", # 個人帳號
|
||||
"ymirliu" # 劉經理
|
||||
]
|
||||
|
||||
for term in test_terms:
|
||||
print(f"\n搜尋: '{term}'")
|
||||
print("-" * 50)
|
||||
|
||||
try:
|
||||
results = search_ldap_groups(term, limit=10)
|
||||
|
||||
if results:
|
||||
print(f"找到 {len(results)} 個結果:")
|
||||
for i, result in enumerate(results, 1):
|
||||
type_text = "組織單位" if result['type'] == 'organizationalUnit' else "群組"
|
||||
print(f" {i}. {result['name']} ({type_text})")
|
||||
print(f" 成員: {result['member_count']}")
|
||||
if result.get('email'):
|
||||
print(f" 郵件: {result['email']}")
|
||||
print(f" DN: {result['dn']}")
|
||||
print()
|
||||
else:
|
||||
print("沒有找到結果")
|
||||
|
||||
except Exception as e:
|
||||
print(f"搜尋錯誤: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def test_specific_search():
|
||||
"""測試特定搜尋詞"""
|
||||
print("\n=== 特定搜尋測試 ===")
|
||||
|
||||
while True:
|
||||
term = input("\n請輸入要搜尋的組織名稱 (或輸入 'quit' 結束): ").strip()
|
||||
|
||||
if term.lower() == 'quit':
|
||||
break
|
||||
|
||||
if not term:
|
||||
continue
|
||||
|
||||
print(f"\n搜尋組織: '{term}'")
|
||||
print("-" * 40)
|
||||
|
||||
try:
|
||||
results = search_ldap_groups(term, limit=15)
|
||||
|
||||
if results:
|
||||
print(f"找到 {len(results)} 個組織:")
|
||||
for i, result in enumerate(results, 1):
|
||||
type_text = "組織單位" if result['type'] == 'organizationalUnit' else "群組"
|
||||
print(f"{i}. {result['name']} ({type_text}, 成員: {result['member_count']})")
|
||||
|
||||
# 提供選擇選項
|
||||
if results:
|
||||
choice = input(f"\n要查看哪個組織的詳細資訊? (1-{len(results)}, 或按 Enter 跳過): ").strip()
|
||||
if choice.isdigit() and 1 <= int(choice) <= len(results):
|
||||
selected = results[int(choice) - 1]
|
||||
print(f"\n{selected['name']} 詳細資訊:")
|
||||
print(f" 類型: {selected['type']}")
|
||||
print(f" 成員數: {selected['member_count']}")
|
||||
print(f" DN: {selected['dn']}")
|
||||
if selected.get('email'):
|
||||
print(f" 群組郵件: {selected['email']}")
|
||||
|
||||
else:
|
||||
print("沒有找到相符的組織")
|
||||
|
||||
except Exception as e:
|
||||
print(f"搜尋失敗: {e}")
|
||||
|
||||
def main():
|
||||
"""主測試函式"""
|
||||
print("組織架構搜尋測試工具")
|
||||
print("=" * 50)
|
||||
print("此工具將測試根據您的 AD 組織架構搜尋群組和組織單位")
|
||||
|
||||
with app.app_context():
|
||||
# 自動測試常見組織名稱
|
||||
test_org_units()
|
||||
|
||||
# 互動式測試
|
||||
choice = input("\n是否要進行互動式組織搜尋測試? (y/N): ").strip().lower()
|
||||
if choice == 'y':
|
||||
test_specific_search()
|
||||
|
||||
print("\n測試完成!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n測試已中斷")
|
||||
except Exception as e:
|
||||
print(f"\n測試發生錯誤: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
137
test_startup.py
137
test_startup.py
@@ -1,137 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
測試系統啟動的腳本
|
||||
用於檢查各個模組是否可以正常導入和初始化
|
||||
"""
|
||||
|
||||
def test_imports():
|
||||
"""測試所有模組導入"""
|
||||
print("🔧 測試模組導入...")
|
||||
|
||||
try:
|
||||
print(" ├─ 測試基本 Flask 組件...")
|
||||
from flask import Flask
|
||||
from flask_login import LoginManager
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
print(" │ ✅ Flask 基本組件導入成功")
|
||||
|
||||
print(" ├─ 測試資料庫模型...")
|
||||
from models import db, User, TempSpec
|
||||
print(" │ ✅ 資料庫模型導入成功")
|
||||
|
||||
print(" ├─ 測試工具函式...")
|
||||
from utils import admin_required, editor_or_admin_required, send_email
|
||||
print(" │ ✅ 工具函式導入成功")
|
||||
|
||||
print(" ├─ 測試 LDAP 工具...")
|
||||
from ldap_utils import authenticate_ldap_user, search_ldap_principals
|
||||
print(" │ ✅ LDAP 工具導入成功")
|
||||
|
||||
print(" ├─ 測試路由模組...")
|
||||
from routes.auth import auth_bp
|
||||
print(" │ ✅ auth 路由導入成功")
|
||||
|
||||
from routes.temp_spec import temp_spec_bp
|
||||
print(" │ ✅ temp_spec 路由導入成功")
|
||||
|
||||
from routes.admin import admin_bp
|
||||
print(" │ ✅ admin 路由導入成功")
|
||||
|
||||
from routes.api import api_bp
|
||||
print(" │ ✅ api 路由導入成功")
|
||||
|
||||
from routes.upload import upload_bp
|
||||
print(" │ ✅ upload 路由導入成功")
|
||||
|
||||
print(" ├─ 測試排程任務...")
|
||||
from tasks import check_expiring_specs
|
||||
print(" │ ✅ 排程任務導入成功")
|
||||
|
||||
print(" └─ 所有模組導入成功!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ 模組導入失敗: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_app_creation():
|
||||
"""測試 Flask 應用程式建立"""
|
||||
print("\n🔧 測試應用程式建立...")
|
||||
|
||||
try:
|
||||
from app import app
|
||||
print(" ✅ Flask 應用程式建立成功")
|
||||
|
||||
# 測試路由註冊
|
||||
with app.app_context():
|
||||
print(f" ✅ 應用程式名稱: {app.name}")
|
||||
print(f" ✅ 註冊的藍圖數量: {len(app.blueprints)}")
|
||||
for bp_name in app.blueprints:
|
||||
print(f" - {bp_name}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ 應用程式建立失敗: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_config():
|
||||
"""測試設定檔"""
|
||||
print("\n🔧 測試設定檔...")
|
||||
|
||||
try:
|
||||
from config import Config
|
||||
print(" ✅ 設定檔導入成功")
|
||||
|
||||
# 檢查重要設定
|
||||
config = Config()
|
||||
print(f" ✅ SECRET_KEY 已設定: {'是' if hasattr(config, 'SECRET_KEY') and config.SECRET_KEY else '否'}")
|
||||
print(f" ✅ DATABASE_URL 已設定: {'是' if hasattr(config, 'SQLALCHEMY_DATABASE_URI') and config.SQLALCHEMY_DATABASE_URI else '否'}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ 設定檔測試失敗: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""主測試函式"""
|
||||
print("=" * 50)
|
||||
print("🚀 暫時規範管理系統 V3 - 啟動測試")
|
||||
print("=" * 50)
|
||||
|
||||
success_count = 0
|
||||
total_tests = 3
|
||||
|
||||
# 測試模組導入
|
||||
if test_imports():
|
||||
success_count += 1
|
||||
|
||||
# 測試設定檔
|
||||
if test_config():
|
||||
success_count += 1
|
||||
|
||||
# 測試應用程式建立
|
||||
if test_app_creation():
|
||||
success_count += 1
|
||||
|
||||
# 結果統計
|
||||
print("\n" + "=" * 50)
|
||||
print(f"📊 測試結果: {success_count}/{total_tests} 個測試通過")
|
||||
|
||||
if success_count == total_tests:
|
||||
print("🎉 所有測試通過!系統可以正常啟動。")
|
||||
return True
|
||||
else:
|
||||
print("⚠️ 部分測試失敗,請檢查上述錯誤訊息。")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
exit(0 if success else 1)
|
Reference in New Issue
Block a user