# 暫時規範管理系統 V4 企業級暫時規範生命週期管理系統,提供完整的文件管理、LDAP整合驗證、智慧通知系統及排程提醒功能。 ## 🚀 系統特色 - **LDAP/AD 整合驗證**:支援企業Active Directory單一登入 - **ONLYOFFICE 線上編輯**:即時協作文件編輯功能 - **智慧通知系統**:動態收件人選擇與自動提醒 - **文件生命週期管理**:完整的建立、啟用、展延、終止流程 - **時區完整支援**:台灣時區 (GMT+8) 全系統支援 - **展延次數控制**:最多2次展延,總效期限制90天 - **Docker 容器化**:一鍵部署環境 ## 📋 功能模組 ### 核心功能 - **文件管理**:Word範本自動化生成與PDF轉換 - **權限控制**:三級權限管理 (Viewer/Editor/Admin) - **歷史追蹤**:完整的操作記錄與版本控制 - **檔案上傳**:支援多種格式的佐證文件上傳 - **展延限制**:最多展延2次,總效期上限90天,防止無限延期 ### 權限說明 - **Viewer(檢視者)**:檢視所有規範、下載PDF檔案、檢視歷史紀錄 - **Editor(編輯者)**:建立新規範、編輯內容、展延/終止規範、下載檔案 - **Admin(管理員)**:所有Editor權限 + 啟用規範 + 刪除規範 ### 智慧通知系統 - **動態收件人選擇**:整合LDAP的即時用戶搜尋 - **郵件記憶功能**:自動記憶並帶出之前使用的通知對象 - **全流程通知**:啟用、展延、終止操作的自動郵件通知 - **自動提醒**:3天與7天到期前的主動提醒郵件 - **排程系統**:每日自動檢查即將到期的規範 ### 編輯器整合 - **ONLYOFFICE整合**:支援Word文件的線上即時編輯 - **Toast UI Editor**:Markdown格式的內容編輯器 - **圖片支援**:內嵌圖片顯示與編輯功能 ## 🏗️ 系統架構 ``` 暫時規範系統 V4 ├── 前端介面 (Flask + Bootstrap 5) ├── 後端邏輯 (Python Flask) ├── 資料庫 (MySQL 外部) ├── LDAP整合 (Active Directory) ├── 文件引擎 (ONLYOFFICE) ├── 快取服務 (Redis) ├── 排程服務 (APScheduler) ├── 反向代理 (Nginx) └── 郵件系統 (SMTP) ``` ## 🛠️ 技術棧 - **後端框架**:Python Flask 3.x - **資料庫ORM**:SQLAlchemy - **前端UI**:Bootstrap 5 + Tom Select - **文件處理**:python-docx, docx2pdf - **認證系統**:Flask-Login + LDAP3 - **排程系統**:Flask-APScheduler - **快取服務**:Redis - **反向代理**:Nginx - **容器化**:Docker + Docker Compose ## 📦 安裝部署 ### 前置需求 - Docker & Docker Compose - 外部 MySQL 8.0+ 資料庫 - LDAP/Active Directory 伺服器 - SMTP 郵件伺服器 ### 快速開始 (Docker) 1. **克隆專案** ```bash git clone cd TEMP_spec_system_V4 ``` 2. **設定環境變數** ```bash cp .env.example .env # 編輯 .env 檔案設定資料庫、LDAP、SMTP 等參數 ``` 3. **使用Docker Compose啟動** ```bash # 建置並啟動所有服務(強制重建以確保使用最新代碼) docker-compose up -d --build # 檢查服務狀態 docker-compose ps # 停止服務 docker-compose down # 查看日誌 docker-compose logs -f ``` 4. **初始化資料庫** ```bash docker-compose exec app python init_db.py ``` 5. **系統訪問** 啟動完成後,您可以通過以下地址訪問系統: - **主系統入口**:http://localhost:12013 (推薦使用,通過 Nginx 代理) - **ONLYOFFICE 文件服務器**:http://localhost:12015 > **注意**: > - 建議使用 Nginx 代理入口 (12013) 訪問系統,具有更好的性能和安全性 > - 首次啟動 ONLYOFFICE 可能需要 2-3 分鐘初始化,請等待容器狀態變為 `healthy` ## ⚙️ 組態設定 ### 環境變數 (.env) ```env # Flask 設定 SECRET_KEY=your_secret_key_here FLASK_ENV=production # 資料庫設定 (外部 MySQL) DATABASE_URL=mysql+pymysql://A060:WLeSCi0yhtc7@mysql.theaken.com:33306/db_A060 # LDAP 設定 (預設配置) LDAP_SERVER=panjit.com.tw LDAP_PORT=389 LDAP_USE_SSL=false LDAP_SEARCH_BASE=DC=panjit,DC=com,DC=tw LDAP_BIND_USER_DN=CN=LdapBind,CN=Users,DC=PANJIT,DC=COM,DC=TW LDAP_BIND_USER_PASSWORD=panjit2481 LDAP_USER_LOGIN_ATTR=userPrincipalName # SMTP 郵件設定 SMTP_SERVER=mail.panjit.com.tw SMTP_PORT=25 SMTP_USE_TLS=false SMTP_USE_SSL=false SMTP_AUTH_REQUIRED=false SMTP_SENDER_EMAIL=temp-spec-system@panjit.com.tw SMTP_SENDER_PASSWORD= # ONLYOFFICE 設定 ONLYOFFICE_URL=http://localhost:12015/ ONLYOFFICE_INTERNAL_URL=http://onlyoffice:80 ONLYOFFICE_JWT_SECRET=your_jwt_secret_key_here # Redis 設定 REDIS_URL=redis://redis:6379/0 # 服務端口設定 ONLYOFFICE_PORT=12015 ``` ## 📚 使用說明 ### 登入規範 **重要**:系統要求使用完整的UPN格式帳號登入 ✅ **正確格式**:`user@panjit.com.tw` ❌ **錯誤格式**:`user` ### 初次設定管理員 系統預設所有使用者為 `viewer` 權限。設定管理員的方式: 1. **程式設定**:修改 `routes/auth.py` 中的預設管理員帳號 2. **手動設定**:在資料庫中更新用戶權限: ```sql UPDATE ts_user SET role='admin' WHERE username='user@panjit.com.tw'; ``` ### 展延次數限制 系統實作嚴格的展延控制機制: - **初次生效**:30天效期 - **第一次展延**:效期變為60天 - **第二次展延**:效期變為90天(達到上限) - **第三次展延**:系統拒絕並顯示錯誤訊息 ### 郵件通知功能 系統具備智慧郵件管理功能: 1. **規範生效時**:輸入通知郵件對象,系統自動記憶 2. **規範終止時**:自動帶出生效時使用的郵件清單,可編輯後發送 3. **規範展延時**:自動帶出郵件清單,修改後更新記錄 ### 排程任務 系統預設每天凌晨 2:00 執行到期檢查任務: - 7天到期提醒 - 3天到期提醒 - 自動發送提醒郵件 ## 🔐 安全性設定 ### LDAP 整合 - 支援 SSL/TLS 加密連線 - 服務帳號權限最小化原則 - 自動用戶同步與權限管控 ### 資料保護 - JWT Token 驗證 - 檔案存取權限控制 - SQL Injection 防護 - XSS 攻擊防護 ## 🐛 疑難排解 ### 常見問題 1. **LDAP 連線失敗** - 檢查防火牆設定 (通常是 389/636 port) - 確認服務帳號權限 - 驗證 LDAP 伺服器位址和搜尋基底 2. **ONLYOFFICE 無法載入文件** - 確認 Document Server 運行狀態:`docker ps` - 檢查容器間網路連線:`docker exec panjit-tempspec-onlyoffice curl -s http://panjit-tempspec-nginx:80/health` - 驗證 JWT Secret 設定是否一致 - 檢查日誌中的網路錯誤:`docker-compose logs onlyoffice | grep ERROR` **常見錯誤**: - `ECONNREFUSED` 錯誤:通常是容器間網路配置問題 - `host.docker.internal` 無法連接:應使用容器名稱而非 host.docker.internal - 文件下載失敗:檢查靜態檔案路徑和 nginx 代理設定 3. **ONLYOFFICE 文件同步問題** - **問題描述**:在 OnlyOffice 編輯器中編輯並儲存文件後,下載的 Word 文件沒有包含最新的編輯內容 **解決方案**: - 系統已增強 OnlyOffice 回調處理機制,支援多種儲存狀態 - 改善了文件同步邏輯,確保編輯內容正確儲存到伺服器 - 新增詳細的回調日誌記錄,便於問題診斷 **檢查方法**: ```bash # 查看 OnlyOffice 回調日誌 docker-compose logs -f app | grep "OnlyOffice callback" # 檢查文件儲存狀態 docker-compose logs -f app | grep "Document saved successfully" # 驗證文件更新時間 docker exec panjit-tempspec-app ls -la uploads/ ``` **技術細節**: - 回調處理現在支援 status=2 (自動儲存) 和 status=6 (強制儲存) - 增加了 JWT Token 驗證以確保回調安全性 - 改善錯誤處理和檔案下載邏輯 - 修正回調中的 URL 路由,將 localhost:12015 轉換為容器間通信地址 panjit-tempspec-onlyoffice:80 4. **時區設定問題** - **問題描述**:系統時間顯示為 GMT+0,但正確時區應該是 GMT+8(台灣時區) **解決方案**: - 建立完整的時區處理模組 `utils/timezone.py` - 修正所有資料庫時間欄位使用台灣時區 - 更新前端模板使用時區轉換 filter - 設定 Docker 容器環境變數 `TZ: Asia/Taipei` **檢查方法**: ```bash # 檢查容器時區設定 docker exec panjit-tempspec-app date # 測試時區轉換功能 docker exec panjit-tempspec-app python -c "from utils.timezone import taiwan_now, format_taiwan_time; print(format_taiwan_time(taiwan_now()))" ``` **技術細節**: - 新增 `taiwan_now()` 函數替代 `datetime.utcnow()` - 支援 `date` 和 `datetime` 物件的時區轉換 - 前端模板 filter:`|taiwan_time` 和 `|taiwan_date` - 自動處理 naive datetime 和 timezone-aware datetime 5. **展延次數限制功能** - **功能說明**:防止暫時規範無限延期,確保企業治理合規 **限制規則**: - 初次生效:30天效期 - 第一次展延:效期變為60天 - 第二次展延:效期變為90天(達到上限) - 第三次展延:系統拒絕並顯示錯誤訊息 **實作功能**: - 後端邏輯檢查:當 `extension_count >= 2` 時拒絕展延 - 前端介面優化:超過限制時展延按鈕變為不可用 - 視覺化顯示:展延次數進度和剩餘次數 - 樣式改進:深色背景下清楚可見的展延狀態顯示 6. **郵件發送失敗** - 確認 SMTP 設定正確 - 檢查郵件伺服器認證設定 - 驗證防火牆規則 (Port 25/587/465) 7. **排程任務未執行** - 檢查 APScheduler 初始化 - 確認應用程式持續運行 - 查看系統日誌 8. **容器間網路通訊問題** - 檢查所有容器是否在同一網路:`docker network ls` - 驗證容器名稱解析:`docker exec container1 ping container2` - 確認端口映射:`docker-compose ps` **OnlyOffice 網路問題修正**: ```bash # 檢查 OnlyOffice 能否連接到 Flask 應用 docker exec panjit-tempspec-onlyoffice curl -I http://panjit-tempspec-nginx:80/static/ # 檢查 Flask 應用日誌 docker-compose logs -f app # 重新構建有網路修正的應用 docker-compose up -d --build app ``` ### 日誌查看 ```bash # Docker 環境 docker-compose logs -f app # OnlyOffice 相關日誌 docker-compose logs -f onlyoffice docker exec panjit-tempspec-onlyoffice tail -f /var/log/onlyoffice/documentserver/docservice/out.log # Redis 日誌 docker-compose logs -f redis # Nginx 日誌 docker-compose logs -f nginx ``` ## 🤝 開發指南 ### 程式碼結構 ``` ├── app.py # 主應用程式 ├── config.py # 組態設定 ├── models.py # 資料模型 ├── tasks.py # 排程任務 ├── wsgi.py # WSGI 入口點 ├── gunicorn.conf.py # Gunicorn 配置 ├── routes/ # 路由模組 │ ├── __init__.py │ ├── auth.py # 認證相關 │ ├── temp_spec.py # 暫規管理 │ ├── upload.py # 檔案上傳 │ ├── admin.py # 管理功能 │ └── api.py # API介面 ├── templates/ # 前端範本 ├── static/ # 靜態檔案 ├── utils/ # 工具模組 │ ├── __init__.py # 工具函式 │ └── timezone.py # 時區處理 ├── ldap_utils.py # LDAP 工具 ├── cache_utils.py # 快取工具 ├── cdn_utils.py # CDN 工具 ├── monitor.py # 監控工具 └── nginx/ # Nginx 配置 ├── Dockerfile ├── nginx.conf └── conf.d/ ``` ### 容器架構 - **panjit-tempspec-app**: Flask 應用程式容器 - **panjit-tempspec-nginx**: Nginx 反向代理容器 - **panjit-tempspec-onlyoffice**: OnlyOffice 文件服務器容器 - **panjit-tempspec-redis**: Redis 快取服務容器 ### 網路配置 所有容器運行在 `tempspec-network` 橋接網路中,確保容器間通信: - 外部訪問:通過 Nginx (port 12013) 和 OnlyOffice (port 12015) - 內部通信:使用容器名稱作為主機名 ## 📄 授權條款 本專案採用 MIT 授權條款。 ## 🆕 版本歷程 ### v4.0.0 (最新版本) - 🆕 新增台灣時區 (GMT+8) 完整支援 - 🆕 實作展延次數限制功能(最多2次,總效期90天) - 🆕 修正 OnlyOffice 文件同步問題 - 🎨 改進規範列表頁面樣式和用戶體驗 - 🔧 修正時區 filter 支援 date 物件處理 - 🗑️ 移除舊版 utils.py,改用模組化架構 - 🔧 修正容器間網路通信問題 - 🆕 新增 Redis 快取服務 - 🆕 新增 Nginx 反向代理 ### v3.2.0 - 🆕 新增郵件通知記憶功能 - 🆕 支援 Port 25 無認證 SMTP - ♻️ 優化郵件管理邏輯 - 🗑️ 移除測試檔案和調試代碼 ### v3.1.0 - 🆕 新增 LDAP/AD 整合驗證 - 🆕 整合 ONLYOFFICE 線上編輯器 - 🆕 實作智慧通知系統 - 🆕 新增自動排程提醒功能 - 🆕 支援 Docker 容器化部署 ### v3.0.0 - ♻️ 重構權限管理系統 - 🗑️ 移除本地帳號管理功能 --- **暫時規範管理系統 V4** - 讓企業文件管理更智慧、更高效!