diff --git a/backend/app/routers/financial.py b/backend/app/routers/financial.py index d45b31d..c286a01 100644 --- a/backend/app/routers/financial.py +++ b/backend/app/routers/financial.py @@ -669,13 +669,77 @@ async def generate_analysis( # Initialize analysis client with configured model client = AnalysisClient(api_key=api_key, base_url=base_url, model=model) + # Prepare dependency context for single-module generation + # If the requested module declares dependencies, generate them first and inject their outputs + context = {} + try: + dependencies = analysis_cfg.get("dependencies", []) or [] + if dependencies: + # Load full modules config to resolve dependency graph + analysis_config_full = load_analysis_config() + modules_config = analysis_config_full.get("analysis_modules", {}) + + # Collect all transitive dependencies + all_required = set() + + def collect_all_deps(mod_name: str): + for dep in modules_config.get(mod_name, {}).get("dependencies", []) or []: + if dep not in all_required: + all_required.add(dep) + collect_all_deps(dep) + + for dep in dependencies: + all_required.add(dep) + collect_all_deps(dep) + + # Build subgraph and topologically sort + graph = {name: [d for d in (modules_config.get(name, {}).get("dependencies", []) or []) if d in all_required] for name in all_required} + in_degree = {u: 0 for u in graph} + for u, deps in graph.items(): + for v in deps: + in_degree[v] += 1 + queue = [u for u, deg in in_degree.items() if deg == 0] + order = [] + while queue: + u = queue.pop(0) + order.append(u) + for v in graph.get(u, []): + in_degree[v] -= 1 + if in_degree[v] == 0: + queue.append(v) + if len(order) != len(graph): + # Fallback: if cycle detected, just use any order + order = list(all_required) + + # Generate dependencies in order + completed = {} + for mod in order: + cfg = modules_config.get(mod, {}) + dep_ctx = {d: completed.get(d, "") for d in (cfg.get("dependencies", []) or [])} + dep_client = AnalysisClient(api_key=api_key, base_url=base_url, model=cfg.get("model", model)) + dep_result = await dep_client.generate_analysis( + analysis_type=mod, + company_name=company_name, + ts_code=ts_code, + prompt_template=cfg.get("prompt_template", ""), + financial_data=financial_data, + context=dep_ctx, + ) + completed[mod] = dep_result.get("content", "") if dep_result.get("success") else "" + + context = {dep: completed.get(dep, "") for dep in dependencies} + except Exception: + # Best-effort context; if anything goes wrong, continue without it + context = {} + # Generate analysis result = await client.generate_analysis( analysis_type=analysis_type, company_name=company_name, ts_code=ts_code, prompt_template=prompt_template, - financial_data=financial_data + financial_data=financial_data, + context=context, ) logger.info(f"[API] Analysis generation completed, success={result.get('success')}") diff --git a/frontend/src/app/report/[symbol]/page.tsx b/frontend/src/app/report/[symbol]/page.tsx index f59b420..8994a73 100644 --- a/frontend/src/app/report/[symbol]/page.tsx +++ b/frontend/src/app/report/[symbol]/page.tsx @@ -1491,6 +1491,7 @@ export default function ReportPage() { : '待开始'} + {/* 失败时的“重新分析”按钮(兼容原逻辑) */} {state.error && !state.loading && ( + )} {state.error && ( diff --git a/scripts/stop.sh b/scripts/stop.sh index fb5c639..f875f5d 100755 --- a/scripts/stop.sh +++ b/scripts/stop.sh @@ -8,3 +8,4 @@ echo "All pm2 applications stopped." echo "Deleting all pm2 processes..." pm2 delete all echo "All pm2 processes deleted." +