From b8ca75609003525b7cf3852c656d5d0ce7c1e46b Mon Sep 17 00:00:00 2001 From: OoO Date: Mon, 18 May 2026 14:39:43 +0800 Subject: [PATCH] fix: align ppt auto generation targets --- config.py | 2 +- routes/openclaw_bot_routes.py | 27 ++++++++++++++++++----- services/ppt_auto_generation_service.py | 8 ++++--- tests/test_ppt_auto_generation_service.py | 7 +++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/config.py b/config.py index 987bea8..65ca897 100644 --- a/config.py +++ b/config.py @@ -320,7 +320,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.183" +SYSTEM_VERSION = "V10.184" LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log') public_url = PUBLIC_URL # 用於模板顯示 diff --git a/routes/openclaw_bot_routes.py b/routes/openclaw_bot_routes.py index 35caf3f..6889369 100644 --- a/routes/openclaw_bot_routes.py +++ b/routes/openclaw_bot_routes.py @@ -3146,7 +3146,21 @@ def _generate_ppt_cmd(sub_type: str, sub_arg: str, _chat_id: int, target: str, elif sub_type in ('strategy', '策略'): period_label = '日報' - if sub_arg and re.fullmatch(r'\d{4}[/-]\d{1,2}[/-]\d{1,2}', sub_arg): + range_dates = re.findall(r'\d{4}[/-]\d{1,2}[/-]\d{1,2}', sub_arg or '') + if len(range_dates) >= 2: + start_str = normalize_date(range_dates[0]) + end_str = normalize_date(range_dates[1]) + date_str = f'{start_str}~{end_str}' + try: + start_dt = datetime.strptime(start_str.replace('/', '-'), '%Y-%m-%d') + end_dt = datetime.strptime(end_str.replace('/', '-'), '%Y-%m-%d') + if start_dt.year == end_dt.year and start_dt.month == end_dt.month and start_dt.day == 1: + period_label = f'{end_dt.year}/{end_dt.month:02d} 月策略(截至 {end_dt.month:02d}/{end_dt.day:02d})' + else: + period_label = f'{start_str}~{end_str} 策略' + except Exception: + period_label = f'{start_str}~{end_str} 策略' + elif sub_arg and re.fullmatch(r'\d{4}[/-]\d{1,2}[/-]\d{1,2}', sub_arg): date_str = normalize_date(sub_arg) start_str, end_str = date_str, date_str period_label = f'{date_str} 日策略' @@ -3603,10 +3617,13 @@ def _generate_ppt_cmd(sub_type: str, sub_arg: str, _chat_id: int, target: str, elif sub_type in ('market_intel', 'intel', '市場情報', '情報週報'): # /ppt market_intel 本週市場情報 from datetime import datetime as _dt, timedelta as _td - today = now.date() if hasattr(now, 'date') else now - # 對齊週一作為週起點 - week_start = today - _td(days=today.weekday()) - week_label = f"{week_start.strftime('%Y/%m/%d')} 起一週" + if sub_arg and '起一週' in sub_arg: + week_label = sub_arg.strip() + else: + today = now.date() if hasattr(now, 'date') else now + # 對齊週一作為週起點 + week_start = today - _td(days=today.weekday()) + week_label = f"{week_start.strftime('%Y/%m/%d')} 起一週" params = {'report_type': 'market_intel', 'week': week_label} cached, cached_ai = _load_cached_ppt_path_and_analysis('market_intel', params) diff --git a/services/ppt_auto_generation_service.py b/services/ppt_auto_generation_service.py index 0fcf373..d8ac07d 100644 --- a/services/ppt_auto_generation_service.py +++ b/services/ppt_auto_generation_service.py @@ -244,6 +244,8 @@ def build_defined_ppt_jobs( promo_prev_end = (target_dt - timedelta(days=7)).strftime("%Y/%m/%d") promo_arg = f"{promo_start}-{target}" promo_compare_arg = f"近7日:{promo_start}-{target}|前7日:{promo_prev_start}-{promo_prev_end}" + strategy_label = f"{month_label} 月策略(截至 {target_dt.strftime('%m/%d')})" + strategy_arg = f"{month_start}-{target}" job_map = { "daily": PPTAutoJob("daily", "每日日報", "daily", target, target, target, { @@ -267,8 +269,8 @@ def build_defined_ppt_jobs( "ttm": PPTAutoJob("ttm", "TTM 滾動 12 月", "ttm", "", target, ttm_label, { "report_type": "ttm", "period": ttm_label, }), - "strategy": PPTAutoJob("strategy", "策略(月)", "strategy", month_arg, target, f"{month_label} 月策略", { - "report_type": "strategy", "start": month_start, "end": month_end, "label": f"{month_label} 月策略", + "strategy": PPTAutoJob("strategy", "策略(月)", "strategy", strategy_arg, target, strategy_label, { + "report_type": "strategy", "start": month_start, "end": target, "label": strategy_label, }), "competitor": PPTAutoJob("competitor", "競品(月)", "competitor", "monthly", target, f"{month_label} 月比較", { "report_type": "competitor", "start": month_start, "end": target, "label": f"{month_label} 月比較", @@ -297,7 +299,7 @@ def build_defined_ppt_jobs( "new_product": PPTAutoJob("new_product", "新品追蹤", "new_product", "30", target, "近 30 天", { "report_type": "new_product", "days": 30, }), - "market_intel": PPTAutoJob("market_intel", "市場情報", "market_intel", "", target, week_label, { + "market_intel": PPTAutoJob("market_intel", "市場情報", "market_intel", week_label, target, week_label, { "report_type": "market_intel", "week": week_label, }), "price_elasticity": PPTAutoJob("price_elasticity", "價格甜蜜點", "price_elasticity", "90", target, "全平台近 90 天", { diff --git a/tests/test_ppt_auto_generation_service.py b/tests/test_ppt_auto_generation_service.py index 6ffa48d..7aa359b 100644 --- a/tests/test_ppt_auto_generation_service.py +++ b/tests/test_ppt_auto_generation_service.py @@ -19,14 +19,15 @@ def test_build_defined_ppt_jobs_uses_latest_date(): assert by_type["quarterly"].sub_arg == "2026/Q2" assert by_type["half_yearly"].sub_arg == "2026/H1" assert by_type["annual"].sub_arg == "2026" - assert by_type["strategy"].sub_arg == "2026/05" + assert by_type["strategy"].sub_arg == "2026/05/01-2026/05/11" + assert by_type["market_intel"].sub_arg == "2026/05/11 起一週" assert by_type["competitor"].sub_arg == "monthly" assert by_type["promo"].sub_arg == "2026/05/05-2026/05/11" assert by_type["strategy"].expected_params == { "report_type": "strategy", "start": "2026/05/01", - "end": "2026/05/31", - "label": "2026/05 月策略", + "end": "2026/05/11", + "label": "2026/05 月策略(截至 05/11)", }