feat(ppt): redesign all 6 reports to professional standard + cache versioning
All checks were successful
CD Pipeline / deploy (push) Successful in 13m18s

PPT 模板全面升版至市場專業標準(McKinsey / BCG 月報級別):

Monthly v3.1(10 頁)
- 暖紙感封面(去黑底)+ elevator pitch(亮點/警訊/動能徽章)
- KPI 卡含 △% vs 上月 + 紅綠燈、YoY 同期對比帶
- matplotlib 業績趨勢折線(本月+上月+日均線+高低點)
- 品類分析雙視圖:橫條 + 帕雷托累計(80% 主力線)
- TOP 50 商品(自動分頁)+ vs 上月 △ 排名變化 / 🆕 新進榜
- MCP 情報 4 卡片結構化、AI 行動結構化分區、附錄頁

Daily / Weekly / Strategy / Promo / Competitor v3.0
- 統一暖紙封面、AI 頁去黑底改暖紙 + 焦糖橘色條
- 日週改 matplotlib 折線(含日均線、高低點)
- 全部加附錄頁(資料來源 / 計算口徑 / 模板版本)

Cache 版本控制
- TEMPLATE_VERSIONS 字典自動注入 cache key (tpl_ver)
- 模板升版舊快取自動 miss → 重生
- 新增 _invalidate_ppt_cache() 與 cleanup_expired_ppt_cache() helper
- 新增 /cache status / flush / cleanup Telegram 指令

字型系統
- _set_run_fonts() 用 lxml 直寫 a:latin/a:ea,中英分軌
- 中文走 Microsoft JhengHei,數字/英文走 Consolas(點陣等寬)
- Dockerfile 加 fonts-noto-cjk + fonts-noto-cjk-extra

部署排程
- scripts/install_ppt_cleanup.sh 一鍵安裝 launchd(每日 03:15)
- scripts/ppt_cleanup.sh 清 7 天前過期 PPT 檔 + DB row

資料層
- routes monthly: query_monthly_summary LIMIT 10 → 50,補 orders 欄位
- routes monthly: 拉 prev_month / prev_year 比較資料供 KPI △ 與商品 △ 計算

煙霧測試 6/6 全綠:
- 日報 v3.0 (5 頁) / 週報 v3.0 (6 頁) / 月報 v3.1 (10 頁)
- 策略 v3.0 (6 頁) / 促銷 v3.0 (6 頁) / 競品 v3.0 (5 頁)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
OoO
2026-05-02 16:26:27 +08:00
parent 0232dbb902
commit 38967ceea3
6 changed files with 1872 additions and 211 deletions

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
com.openclaw.ppt-cleanup.plist
每日凌晨 03:15 清理 7 天前過期的 PPT 檔 + DB row。
安裝(一次性):
bash scripts/install_ppt_cleanup.sh
手動觸發(測試):
launchctl start com.openclaw.ppt-cleanup
停用 / 解除:
launchctl unload ~/Library/LaunchAgents/com.openclaw.ppt-cleanup.plist
rm ~/Library/LaunchAgents/com.openclaw.ppt-cleanup.plist
-->
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.openclaw.ppt-cleanup</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>__SCRIPT_PATH__</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>15</integer>
</dict>
<key>StandardOutPath</key>
<string>__LOG_DIR__/ppt_cleanup.stdout.log</string>
<key>StandardErrorPath</key>
<string>__LOG_DIR__/ppt_cleanup.stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PROJECT_DIR</key>
<string>__PROJECT_DIR__</string>
<key>DAYS_OLD</key>
<string>7</string>
</dict>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>

74
scripts/install_ppt_cleanup.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# scripts/install_ppt_cleanup.sh
# 一鍵安裝:將 PPT cleanup 排程到 macOS launchd每日 03:15 執行)。
#
# 用法:
# bash scripts/install_ppt_cleanup.sh # 安裝
# bash scripts/install_ppt_cleanup.sh --uninstall # 解除安裝
# bash scripts/install_ppt_cleanup.sh --test # 安裝後立刻跑一次
set -euo pipefail
# ── 路徑解析 ────────────────────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
LOG_DIR="${PROJECT_DIR}/logs"
SCRIPT_PATH="${SCRIPT_DIR}/ppt_cleanup.sh"
PLIST_NAME="com.openclaw.ppt-cleanup"
PLIST_SRC="${SCRIPT_DIR}/${PLIST_NAME}.plist"
PLIST_DST="${HOME}/Library/LaunchAgents/${PLIST_NAME}.plist"
mkdir -p "$LOG_DIR"
mkdir -p "$(dirname "$PLIST_DST")"
chmod +x "$SCRIPT_PATH"
# ── 解除安裝 ────────────────────────────────────────────────────────────
if [[ "${1:-}" == "--uninstall" ]]; then
if launchctl list | grep -q "$PLIST_NAME"; then
launchctl unload "$PLIST_DST" 2>/dev/null || true
fi
rm -f "$PLIST_DST"
echo "✅ 已解除安裝 ${PLIST_NAME}"
exit 0
fi
# ── 安裝 ────────────────────────────────────────────────────────────────
echo "🔧 安裝 PPT cleanup launchd job..."
echo " PROJECT_DIR : $PROJECT_DIR"
echo " SCRIPT_PATH : $SCRIPT_PATH"
echo " LOG_DIR : $LOG_DIR"
echo " PLIST_DST : $PLIST_DST"
# 替換 plist 中的 placeholder
sed -e "s|__SCRIPT_PATH__|${SCRIPT_PATH}|g" \
-e "s|__LOG_DIR__|${LOG_DIR}|g" \
-e "s|__PROJECT_DIR__|${PROJECT_DIR}|g" \
"$PLIST_SRC" > "$PLIST_DST"
# 重新載入 launchd job
launchctl unload "$PLIST_DST" 2>/dev/null || true
launchctl load "$PLIST_DST"
echo "✅ 已安裝 ${PLIST_NAME}(每日 03:15 執行)"
echo ""
echo "驗證:"
launchctl list | grep "$PLIST_NAME" || echo " job 尚未列出,可重啟 Mac 或執行 launchctl load"
# ── 即刻測試 ────────────────────────────────────────────────────────────
if [[ "${1:-}" == "--test" ]]; then
echo ""
echo "🚀 立即觸發一次測試..."
launchctl start "$PLIST_NAME"
sleep 2
echo "📋 stdout 最後 20 行:"
tail -20 "${LOG_DIR}/ppt_cleanup.stdout.log" 2>/dev/null || echo " (尚無輸出)"
echo "📋 stderr 最後 20 行:"
tail -20 "${LOG_DIR}/ppt_cleanup.stderr.log" 2>/dev/null || echo " (無 stderr正常"
fi
echo ""
echo "🛠 後續操作:"
echo " 立即觸發: launchctl start $PLIST_NAME"
echo " 解除安裝: bash $0 --uninstall"
echo " 查看日誌: tail -f ${LOG_DIR}/ppt_cleanup.log"

27
scripts/ppt_cleanup.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# scripts/ppt_cleanup.sh
# 由 launchd / cron 呼叫 — 清理 7 天前過期的 PPT 檔 + DB row。
# 安全執行:失敗時不會 raise只寫 log。
set -euo pipefail
PROJECT_DIR="${PROJECT_DIR:-/Users/ooo/Documents/momo_pro_system}"
VENV_PY="${VENV_PY:-${PROJECT_DIR}/venv/bin/python3}"
LOG_FILE="${LOG_FILE:-${PROJECT_DIR}/logs/ppt_cleanup.log}"
DAYS_OLD="${DAYS_OLD:-7}"
mkdir -p "$(dirname "$LOG_FILE")"
cd "$PROJECT_DIR"
{
echo "[$(date +'%Y-%m-%d %H:%M:%S')] PPT cleanup start (days_old=$DAYS_OLD)"
"$VENV_PY" -c "
from routes.openclaw_bot_routes import cleanup_expired_ppt_cache
import json
stat = cleanup_expired_ppt_cache(days_old=$DAYS_OLD)
print('result:', json.dumps(stat, ensure_ascii=False))
" 2>&1 || echo "[ERROR] cleanup failed"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] PPT cleanup end"
echo "---"
} >> "$LOG_FILE"