#!/usr/bin/env python3 """危大方案独立看板 - 2026开工版 · 简化状态""" import pandas as pd, warnings, json from pathlib import Path warnings.filterwarnings('ignore') DATA_DATE = '2026-06-08' BASE = Path(f'/mnt/y/Openclaw_Hub/05_表达Express/专项施工方案数据看板/data/{DATA_DATE}/cleaned') df = pd.read_parquet(BASE / 'methods_cleaned.parquet') valid = df[df['是否有效登记'] == True].copy() valid['开工年份'] = pd.to_datetime(valid['分部分项工程计划开工日期'], errors='coerce').dt.year y2026 = valid[valid['开工年份'] == 2026].copy() def simple_status(s): s = str(s) if any(kw in s for kw in ['已审批', '已备案']): return '已完成' return '未完成' y2026['简化状态'] = y2026['方案状态_clean'].apply(simple_status) completed = (y2026['简化状态'] == '已完成').sum() total = len(y2026) oversized = (y2026['是否超一定规模'].astype(str) == '是').sum() # By country country_stats = y2026.groupby('所属国别').agg( 项目数=('项目名称', 'nunique'), 方案总数=('方案名称', 'count'), 已完成=('简化状态', lambda x: (x == '已完成').sum()), 超规=('是否超一定规模', lambda x: (x.astype(str) == '是').sum()), ).reset_index() country_stats['审批率'] = (country_stats['已完成'] / country_stats['方案总数'] * 100).round(0).astype(int) # Project summary ps = y2026.groupby('项目名称').agg( 方案总数=('方案名称', 'count'), 已完成=('简化状态', lambda x: (x == '已完成').sum()), 超规=('是否超一定规模', lambda x: (x.astype(str) == '是').sum()), ).reset_index() ps['未完成'] = ps['方案总数'] - ps['已完成'] ps['审批率'] = (ps['已完成'] / ps['方案总数'] * 100).round(0).astype(int) ps['国别'] = ps['项目名称'].map(y2026.groupby('项目名称')['所属国别'].first()) ps = ps.sort_values('方案总数', ascending=False) # Status breakdown status_counts = y2026['方案状态_clean'].value_counts().to_dict() # Generate HTML rows = [] for _, r in ps.iterrows(): name = r['项目名称'][:60] total_n = int(r['方案总数']) done = int(r['已完成']) undone = int(r['未完成']) sz = int(r['超规']) rate = int(r['审批率']) country = r.get('国别', '') if rate >= 80: cls = 'badge-ok' elif rate >= 50: cls = 'badge-warn' else: cls = 'badge-alert' rows.append(f'{name}{total_n}{done}{sz}{rate}%{country}') country_rows = [] for _, r in country_stats.iterrows(): name = r['所属国别'] c = int(r['审批率']) if c >= 80: cls = 'badge-ok' elif c >= 50: cls = 'badge-warn' else: cls = 'badge-alert' country_rows.append(f'{name}{int(r[\"项目数\"])}{int(r[\"方案总数\"])}{int(r[\"已完成\"])}{int(r[\"超规\"])}{c}%') approved_pct = round(completed/total*100) if total else 0 approved_color = '#22c55e' if approved_pct >= 80 else '#f59e0b' if approved_pct >= 50 else '#ef4444' html = f''' 危大方案编审进度看板 | 2026年开工 | 中东区域公司

🏗️ 危大方案编审进度看板

中国港湾中东区域公司 · 2026年开工项目 · 数据日期:{DATA_DATE}

2026开工方案
{total}
覆盖{len(ps)}个项目
超一定规模
{oversized}
占比 {round(oversized/total*100)}%
已完成审批
{completed}
{total-completed}项未完成
审批完成率
{approved_pct}%
{completed}/{total}
📌 状态说明:已完成 = 已审批或已备案;未完成 = 未审批 / 审批中 / 未知。已作废方案已排除。
📌 范围说明:仅显示分部分项工程计划开工日期在2026年的方案(共{total}项,占全部有效方案{len(valid)}项的{round(total/len(valid)*100)}%)。

📋 项目明细(按方案总数排序)

{rows_html}
项目名称方案已完成超规审批率国别
合计{total}{completed}{oversized}{approved_pct}%

🌍 按国别汇总

{country_rows_html}
国别项目数方案总数已完成超规审批率
''' out = BASE / 'certified_schemes_dashboard.html' out.write_text(html, encoding='utf-8') print(f'✅ {out}') print(f' {len(html):,} bytes') print(f' {total} schemes, {len(ps)} projects, {approved_pct}% completion')