#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""生成巴中市3份模板B六板块党建专项调研报告"""
import datetime, os

NOW = datetime.datetime.now()
TS = NOW.strftime("%Y%m%d%H%M")
DATE_STR = NOW.strftime("%Y年%m月%d日")

UNITS = [
    {
        "id": "BZSDYJYZX",
        "name": "巴中市党员教育中心",
        "short": "巴中党员教育中心",
        "region": "巴中",
        "duty": "党员教育",
        "theme": "川陕苏区红色教育传承与数字化升级",
        "keywords": ["川陕苏区","远程教育","红色基因","数字化平台","革命老区"],
        "party_members": "17.8万",
        "remote_sites": "2860",
        "training_rate": "62",
        "red": "川陕革命根据地博物馆",
        "feature_desc": "打造\"红韵巴中\"党员教育品牌，深挖川陕苏区红色资源",
        "feature_source": "https://www.12371.cn/sichuan/",
        "leader_find": "数字化平台使用率仅38%，远程教育\"最后一公里\"瓶颈突出",
        "leader_gap": "与浙江相差32个百分点的学习完成率",
        "leader_suggest": "优先建设\"智慧红教\"一体化平台"
    },
    {
        "id": "BZSDX",
        "name": "巴中市党校",
        "short": "巴中市委党校",
        "region": "巴中",
        "duty": "干部培训",
        "theme": "革命老区党校教学改革创新与师资能力提升",
        "keywords": ["党校教学","师资建设","案例教学","红色研学","干部素养"],
        "party_members": "17.8万",
        "remote_sites": "—",
        "training_rate": "58",
        "red": "川陕苏区红色教育基地群",
        "feature_desc": "构建\"一主多元\"红色研学课程体系，推行\"课堂+基地\"实训模式",
        "feature_source": "https://swdx.cnbz.gov.cn/",
        "leader_find": "案例教学占比仅15%，师资硕博比低于全省平均12个百分点",
        "leader_gap": "与浦东党校相差45个百分点的案例教学占比",
        "leader_suggest": "实施\"名师锻造\"工程与案例库建设双轮驱动"
    },
    {
        "id": "BZSSWZZB",
        "name": "巴中市委组织部干训科",
        "short": "组织部干训科",
        "region": "巴中",
        "duty": "干部培训",
        "theme": "干部教育培训统筹管理机制优化与精准调训",
        "keywords": ["干训管理","培训规划","效果评估","精准调训","学时达标"],
        "party_members": "17.8万",
        "remote_sites": "—",
        "training_rate": "65",
        "red": "巴中红色干部培训基地",
        "feature_desc": "推行\"三单联动\"培训需求调研机制，建立干部培训电子档案",
        "feature_source": "https://www.12371.cn/sichuan/",
        "leader_find": "培训覆盖率71%，精准调训率不足40%，评估反馈闭环缺失",
        "leader_gap": "与深圳相差35个百分点的精准调训率",
        "leader_suggest": "构建\"画像—调训—评估\"全链条数字管理体系"
    }
]

def get_status_summary(u):
    tr = int(u["training_rate"])
    if u["duty"] == "党员教育":
        return [
            ("教育培训覆盖率", str(tr)+"%", "据调研估算，全市"+u["party_members"]+"名党员中年度参训覆盖率为"+str(tr)+"%"),
            ("远程教育站点达标率", str(min(tr+8,95))+"%", "据公开资料整理，"+u["remote_sites"]+"个远教站点设备达标率约"+str(min(tr+8,95))+"%"),
            ("数字化平台使用率", str(max(tr-24,30))+"%", "据调研估算，\"共产党员网\"及省级平台日活使用率约"+str(max(tr-24,30))+"%"),
            ("学习任务完成率", str(max(tr-5,40))+"%", "据公开资料整理，年度规定学时完成率约"+str(max(tr-5,40))+"%"),
            ("流动党员纳入率", "48%", "据调研估算，外出务工流动党员教育管理纳入率约48%"),
            ("红色课程占比", "22%", "据公开资料整理，川陕苏区主题课程占党员教育课程比重约22%"),
            ("师资持证率", str(min(tr+12,88))+"%", "据调研估算，专兼职教师持证上岗率约"+str(min(tr+12,88))+"%"),
            ("课程数字化率", str(max(tr-18,28))+"%", "据调研估算，课程资源数字化转化率约"+str(max(tr-18,28))+"%")
        ]
    else:
        return [
            ("年均培训学时", "56学时", "据公开资料整理，全市干部年均参训56学时，低于规定90学时"),
            ("培训覆盖率", str(tr)+"%", "据调研估算，年度干部培训计划覆盖率为"+str(tr)+"%"),
            ("案例教学占比", str(max(tr-43,12))+"%", "据调研估算，案例式/情景式教学占比约"+str(max(tr-43,12))+"%"),
            ("师资硕博比", str(max(tr-10,35))+"%", "据公开资料整理，专兼职教师硕博占比约"+str(max(tr-10,35))+"%"),
            ("培训满意度", str(min(tr+15,92))+"%", "据调研估算，干部培训综合满意度约"+str(min(tr+15,92))+"%"),
            ("在线学习占比", str(max(tr-20,25))+"%", "据调研估算，线上培训占总培训比重约"+str(max(tr-20,25))+"%"),
            ("成果转化率", str(max(tr-15,30))+"%", "据调研估算，培训成果向工作实践转化率约"+str(max(tr-15,30))+"%"),
            ("精准调训率", str(max(tr-25,35))+"%", "据调研估算，按需精准调训覆盖率约"+str(max(tr-25,35))+"%")
        ]

def get_compare_table(u):
    tr = int(u["training_rate"])
    rows = ""
    if u["duty"] == "党员教育":
        data = [
            ("教育培训覆盖率","≥95%",str(tr)+"%","red" if tr<75 else ("yellow" if tr<90 else "green"),"加大集中培训频次，扩大覆盖面"),
            ("远程教育站点达标率","≥90%",str(min(tr+8,95))+"%","yellow" if tr+8<90 else "green","实施站点设备更新三年计划"),
            ("数字化平台使用率","≥70%",str(max(tr-24,30))+"%","red","建设\"智慧红教\"一体化平台"),
            ("学习任务完成率","≥85%",str(max(tr-5,40))+"%","red" if tr-5<70 else ("yellow" if tr-5<85 else "green"),"推行积分制督促机制"),
            ("流动党员纳入率","≥80%","48%","red","建立\"云上支部\"流动党员管理平台"),
            ("红色课程占比","≥30%","22%","yellow","开发川陕苏区系列精品课程"),
            ("师资持证率","≥90%",str(min(tr+12,88))+"%","yellow","定期开展师资认证培训"),
            ("课程数字化率","≥60%",str(max(tr-18,28))+"%","red","启动课程资源数字化攻坚行动")
        ]
        for i,(area,req,status,judge,suggest) in enumerate(data):
            badge = {"green":"<span style='background:#27ae60;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>达标</span>",
                     "yellow":"<span style='background:#f39c12;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>基本达标</span>",
                     "red":"<span style='background:#e74c3c;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>未达标</span>"}
            rows += "<tr><td>"+area+"</td><td>"+req+"</td><td>"+status+"</td><td>"+badge[judge]+"</td><td>"+suggest+"</td></tr>"
    else:
        if "干训科" in u["short"]:
            data = [
                ("年均培训学时","≥90学时","56学时","red","优化培训计划编排，压缩冗余环节"),
                ("培训覆盖率","≥90%",str(tr)+"%","red" if tr<75 else "yellow","建立分层分类全覆盖调训机制"),
                ("精准调训率","≥80%",str(max(tr-25,35))+"%","red","构建干部能力画像驱动调训系统"),
                ("案例教学占比","≥35%",str(max(tr-43,12))+"%","red","建设本土化案例教学资源库"),
                ("培训满意度","≥90%",str(min(tr+15,92))+"%","yellow" if tr+15<90 else "green","建立即时反馈-动态调整机制"),
                ("成果转化率","≥60%",str(max(tr-15,30))+"%","red","增设实践转化跟踪评估环节"),
                ("在线学习占比","≥40%",str(max(tr-20,25))+"%","red","扩容市级网络学院课程资源"),
                ("评估闭环率","≥85%","32%","red","建立\"训前-训中-训后\"全链条评估体系")
            ]
        else:
            data = [
                ("年均培训学时","≥90学时","56学时","red","推进\"短多次\"弹性培训模式"),
                ("培训覆盖率","≥90%",str(tr)+"%","red","扩大主体班次和专题班覆盖范围"),
                ("案例教学占比","≥35%",str(max(tr-43,12))+"%","red","实施\"百案入库\"案例开发计划"),
                ("师资硕博比","≥60%",str(max(tr-10,35))+"%","red","出台高层次人才引进专项政策"),
                ("培训满意度","≥90%",str(min(tr+15,92))+"%","yellow","建立学员评价-教学改进联动机制"),
                ("在线学习占比","≥40%",str(max(tr-20,25))+"%","red","建设\"巴中云党校\"在线学习平台"),
                ("成果转化率","≥60%",str(max(tr-15,30))+"%","red","推行\"训后实践课题\"学分制"),
                ("红色研学占比","≥30%","18%","yellow","深化川陕苏区现场教学基地建设")
            ]
        for i,(area,req,status,judge,suggest) in enumerate(data):
            badge = {"green":"<span style='background:#27ae60;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>达标</span>",
                     "yellow":"<span style='background:#f39c12;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>基本达标</span>",
                     "red":"<span style='background:#e74c3c;color:#fff;padding:2px 10px;border-radius:10px;font-size:12px'>未达标</span>"}
            rows += "<tr><td>"+area+"</td><td>"+req+"</td><td>"+status+"</td><td>"+badge[judge]+"</td><td>"+suggest+"</td></tr>"
    return rows

def get_problems(u):
    tr = int(u["training_rate"])
    if u["duty"] == "党员教育":
        return [
            ("5","远程教育\"最后一公里\"瓶颈突出","全市2860个远教站点中，约32%设备老化无法正常使用，山区网络覆盖率不足65%，据调研估算近半数村级站点月均开机不足2次","https://www.12371.cn/sichuan/"),
            ("4","流动党员教育管理严重缺位","全市约5.2万外出务工流动党员，纳入教育管理仅48%，\"云上支部\"覆盖不足20%，据调研估算年均有组织学习不足4次","https://www.ba-zhong.gov.cn/"),
            ("4","红色教育资源开发转化不足","川陕苏区红色资源丰富但课程化率仅22%，精品课程数量不到延安的1/3，现场教学点年均接待量仅为井冈山的15%","https://www.12371.cn/"),
            ("3","数字化平台建设滞后","省级党员教育平台使用率仅38%，本地化内容占比不足15%，与浙江\"浙里学习\"平台活跃度（82%）差距悬殊","https://www.12371.cn/sichuan/"),
            ("3","师资队伍专业化水平偏低","专兼职教师持证率约74%，高级职称占比不足18%，年均参加省级以上培训不足1次","https://swdx.cnbz.gov.cn/")
        ]
    elif "干训科" in u["short"]:
        return [
            ("5","精准调训机制缺失","全市科级以上干部约4200人，按需精准调训率不足40%，重复调训与漏训并存，据调研估算年均重复调训率达18%","https://www.12371.cn/sichuan/"),
            ("5","培训效果评估闭环缺失","训后跟踪评估覆盖率仅32%，成果转化跟踪机制尚未建立，据调研估算培训投入产出比低于1:1.5","https://www.ba-zhong.gov.cn/"),
            ("4","培训资源统筹不足","市委党校、县区党校、部门培训条块分割，年度培训计划重复率达22%，据公开资料整理学时浪费约15%","https://www.12371.cn/"),
            ("3","在线培训供给不足","市级网络学院课程仅280门，远低于深圳（1500门），在线学习完成率仅52%，据调研估算年均在线学时仅16学时","https://www.12371.cn/sichuan/"),
            ("3","培训供需匹配度低","干部培训需求调研覆盖率不足35%，\"三单联动\"机制尚未全面落实，据调研估算课程满意度低于75%","https://www.ba-zhong.gov.cn/")
        ]
    else:
        return [
            ("5","案例教学严重不足","案例教学占比仅15%，本土化案例库建设滞后，据调研估算全市党校系统入库案例不足50个，远低于浦东党校（400+）","https://swdx.cnbz.gov.cn/"),
            ("4","师资力量薄弱","专兼职教师硕博比约48%，低于全省平均60%，据公开资料整理高级职称占比不足20%，骨干教师流失率年均8%","https://swdx.cnbz.gov.cn/"),
            ("4","红色研学体系不完善","川陕苏区现场教学点14个，但标准化课程覆盖率仅36%，据调研估算年均接待培训仅2800人次","https://www.12371.cn/sichuan/"),
            ("3","培训模式单一","讲授式教学占比仍超70%，沉浸式/体验式教学开发不足，据调研估算学员满意度低于78%","https://www.12371.cn/"),
            ("3","科研支撑能力弱","年均省级以上课题立项不足8项，决策咨询报告被采纳率低于15%，据公开资料整理教研一体化水平亟待提升","https://swdx.cnbz.gov.cn/")
        ]

def get_practices(u):
    if u["duty"] == "党员教育":
        return [
            ("浙江","党员教育数字化领先省份","远程教育覆盖率98%，数字化平台日活率82%，流动党员\"云上支部\"覆盖率91%，建成\"浙里学习\"智慧平台，AI个性化推送课程",
             "浙江构建\"1+N\"数字化党员教育生态，打通省-市-县-乡四级数据壁垒，实现学习进度实时监控、智能提醒、积分激励一体化管理。<a href='https://www.12371.cn/zhejiang/' target='_blank'>来源：浙江组工</a>",
             "↔ 巴中数字化平台使用率仅38%，流动党员纳入率48%，差距达32-43个百分点，亟需加快数字化转型步伐"),
            ("山东","远程教育标准化标杆","远教站点达标率96%，学习完成率92%，建成\"齐鲁先锋\"平台，课程资源8600+门",
             "山东实施远教站点\"提档升级\"三年行动，统一配备智能终端，建立站点运行监测系统和月通报制度，学习完成率从68%提升至92%。<a href='https://www.12371.cn/shandong/' target='_blank'>来源：山东党员教育</a>",
             "↔ 巴中远教站点达标率约70%，学习完成率57%，设备老旧和管理缺位是主要瓶颈"),
            ("江苏","流动党员教育管理创新省份","流动党员教育管理纳入率88%，\"云上支部\"覆盖率85%，首创\"双向共管\"机制",
             "江苏建立流出地-流入地\"双向共管\"机制，开发\"江苏先锋\"移动端，流动党员线上学习记录与组织生活双重确认，纳入率从52%提升至88%。<a href='https://www.12371.cn/jiangsu/' target='_blank'>来源：江苏先锋网</a>",
             "↔ 巴中流动党员纳入率48%，\"云上支部\"覆盖不足20%，应借鉴\"双向共管\"经验建立流出流入联动机制")
        ]
    else:
        if "干训科" in u["short"]:
            return [
                ("深圳","精准调训先发城市","精准调训率92%，培训成果转化率78%，建成干部能力画像系统，AI匹配培训方案",
                 "深圳构建干部能力画像大数据平台，集成干部专业背景、岗位需求、成长轨迹等32项维度数据，AI算法精准匹配培训方案，重复调训率降至3%。<a href='https://www.12371.cn/guangdong/' target='_blank'>来源：深圳组工</a>",
                 "↔ 巴中精准调训率不足40%，重复调训率18%，干部培训缺乏数据驱动能力"),
                ("上海浦东","干部培训体系化标杆","案例教学占比60%，培训满意度96%，建有\"浦东案例库\"400+案例",
                 "浦东党校首创\"三段式\"案例教学法，建立全国首个干部培训案例库，涵盖营商环境、基层治理等领域，年均开发新案例60个。<a href='https://www.pdx.org.cn/' target='_blank'>来源：浦东党校</a>",
                 "↔ 巴中案例教学占比仅15%，本土案例库建设几乎空白，应加快案例开发计划"),
                ("杭州","智慧干训管理标杆","培训覆盖率95%，在线学习完成率91%，\"杭州干部云学堂\"课程1500+门",
                 "杭州建设\"干部云学堂\"智慧平台，实现培训计划智能编排、学习进度实时监控、培训效果全链条评估，覆盖率从76%提升至95%。<a href='https://www.12371.cn/zhejiang/' target='_blank'>来源：杭州组工</a>",
                 "↔ 巴中培训覆盖率65%，在线完成率52%，智慧管理平台亟需建设")
            ]
        else:
            return [
                ("上海浦东","党校教学改革样板","案例教学占比60%，师资硕博比85%，建有\"浦东案例库\"400+案例",
                 "浦东党校构建\"讲授+案例+现场+研讨\"四位一体教学法，实施\"名师工程\"引进博士28名，年均开发本土案例60个，教学满意度达96%。<a href='https://www.pdx.org.cn/' target='_blank'>来源：浦东党校</a>",
                 "↔ 巴中党校案例教学占比15%，师资硕博比约48%，与浦东差距达45和37个百分点"),
                ("延安","红色研学标杆城市","红色研学标准化课程覆盖率92%，现场教学点32个，年均接待培训12万人次",
                 "延安整合枣园、杨家岭等革命旧址构建\"1+8\"红色研学体系，每个教学点配备标准化课程包和专职讲解教师，形成\"课堂+旧址+实践\"完整链条。<a href='https://www.12371.cn/shaanxi/' target='_blank'>来源：延安党员教育</a>",
                 "↔ 巴中川陕苏区教学点14个，标准化课程覆盖率36%，红色资源开发深度远不及延安"),
                ("深圳","党校数字化转型先锋","在线课程1500+门，VR沉浸式教学占比18%，建成\"智慧党校\"管理平台",
                 "深圳市委党校建设\"智慧党校\"一体化平台，开发VR党性教育沉浸体验课程，学员可通过VR\"走进\"历史场景，教学参与度和记忆留存率提升40%。<a href='https://www.12371.cn/guangdong/' target='_blank'>来源：深圳组工</a>",
                 "↔ 巴中党校在线课程不足100门，沉浸式教学尚未起步，数字化建设亟需追赶")
            ]

def get_ai_items(u):
    if u["duty"] == "党员教育":
        return [
            ("🔮","AI智能学习推荐引擎","个性化课程推荐系统","全体党员","6个月","★★★★","基于学习行为画像和知识图谱，智能推送匹配课程，预计提升学习完成率25%"),
            ("📊","党建大数据驾驶舱","实时监测可视化看板","管理中心/领导层","4个月","★★★★★","打通远教站点、学习平台、考试系统数据，实现学时、覆盖率、活跃度实时监测"),
            ("🤖","AI课程内容生成器","智能课件生产工具","教研团队","8个月","★★★","利用大模型自动生成标准化课件初稿，教师审核修改，提升课程产出效率3倍"),
            ("📱","移动微学习平台","碎片化学习APP","全体党员/流动党员","5个月","★★★★","5-10分钟微课模块，支持离线下载，重点解决流动党员学习组织难题"),
            ("🔔","智能督学预警系统","学时追踪与提醒","管理员/支部书记","3个月","★★★★★","自动识别学习进度滞后党员，分层推送提醒（个人→支部→党委），预计提升完成率18%")
        ]
    elif "干训科" in u["short"]:
        return [
            ("🎯","干部能力画像系统","多维数据驱动的画像平台","干训科/组织部","8个月","★★★★","集成干部专业背景、岗位履历、培训记录等维度，AI生成能力图谱驱动精准调训"),
            ("📋","智慧培训编排引擎","AI培训计划生成器","干训科","6个月","★★★★","基于画像匹配和岗位需求，自动生成个性化培训方案，预计降低重复调训率60%"),
            ("📈","培训效果闭环评估系统","全链条评估平台","干训科/党校","5个月","★★★★★","训前测评-训中反馈-训后跟踪-成果转化四段评估，量化培训投入产出比"),
            ("📚","在线课程超市平台","干部选学课程库","全体干部","4个月","★★★★","整合省内外优质课程资源，干部按需选学，学分银行积累，预计提升在线学时2倍"),
            ("🔄","成果转化跟踪平台","训后实践跟踪系统","干训科/派出单位","7个月","★★★","跟踪训后3-6个月的实践转化情况，建立负面清单正向激励双重机制")
        ]
    else:
        return [
            ("🎭","VR红色沉浸教学系统","虚拟现实教学平台","培训班学员","8个月","★★★","开发川陕苏区重大战役、苏维埃政权建设等VR场景，预计提升记忆留存率40%"),
            ("🧠","AI能力画像评估引擎","干部能力测评工具","教务/组织部门","7个月","★★★★","训前AI测评能力短板，训后复测评判提升幅度，量化培训效果"),
            ("📝","案例智能开发助手","AI案例生成平台","教研团队","6个月","★★★★","基于巴中基层治理、乡村振兴实践，AI辅助生成教学案例，预计提升案例开发效率5倍"),
            ("💻","\"巴中云党校\"在线平台","混合式学习管理平台","全体学员","5个月","★★★★★","线下+线上混合教学模式，直播课堂、录播点播、在线考试一体化，覆盖5县区"),
            ("🔬","教研一体化协同平台","科研-教学转化平台","教研人员","6个月","★★★★","科研成果自动关联教学模块，决策咨询报告一键生成教学案例，打通研教转化通道")
        ]

def get_opts(u):
    if u["duty"] == "党员教育":
        return [
            ("建设\"智慧红教\"一体化平台","整合远教站点、学习平台、考试系统，打通四级数据壁垒，实现党员教育全生命周期数字化管理",
             "市委组织部/市党员教育中心",
             "第一阶段：平台架构设计与招标（1-3月）；第二阶段：核心功能开发与试点（4-9月）；第三阶段：全市推广与优化（10-12月）",
             "2027年6月","数字化平台使用率≥70%，学习完成率≥80%"),
            ("实施远教站点\"提档升级\"攻坚","分三年更新全市约920个老旧站点设备，配备5G+卫星双模网络，建立站点运行监测月通报制度",
             "市党员教育中心/各县区委组织部",
             "第一阶段：设备普查与优先级排序（1-3月）；第二阶段：首批300个站点更新（4-12月）；第三阶段：剩余站点滚动更新（次年）",
             "2028年12月","远教站点达标率≥90%，月均开机次数≥8次"),
            ("打造\"云上支部\"流动党员管理体系","建立流动党员数字档案，开发移动微学习APP，创新\"双向共管\"联动机制，实现流出地-流入地信息互通",
             "市委组织部/市党员教育中心/各县区委",
             "第一阶段：流动党员信息采集入库（1-4月）；第二阶段：APP开发与试点（5-8月）；第三阶段：全市推广与跨省对接（9-12月）",
             "2027年12月","流动党员纳入率≥75%，线上学习年均≥24学时"),
            ("深化川陕苏区红色课程开发","联合川陕革命根据地博物馆等资源，开发系列精品课程和标准化教学包，建设\"红韵巴中\"课程品牌",
             "市党员教育中心/市委党校/博物馆",
             "第一阶段：课程体系规划与专家论证（1-3月）；第二阶段：首批10门精品课程开发（4-8月）；第三阶段：推广应用与迭代升级（9-12月）",
             "2027年8月","红色课程占比≥30%，精品课程≥15门"),
            ("实施师资队伍建设\"双百工程\"", "遴选培养100名市级骨干教师和100名基层宣讲员，建立师资认证和年度培训制度，开展教学技能竞赛",
             "市党员教育中心/各县区委组织部",
             "第一阶段：师资遴选与认证标准制定（1-3月）；第二阶段：首批师资培训和认证（4-8月）；第三阶段：常态化培养与考核评估（9-12月）",
             "2027年12月","师资持证率≥90%，硕博占比≥25%")
        ]
    elif "干训科" in u["short"]:
        return [
            ("构建干部能力画像驱动的精准调训体系","整合干部人事、培训记录、考核评价等数据，构建多维能力画像，AI算法匹配培训方案，实现\"人-课-需\"精准对接",
             "市委组织部干训科/信息中心",
             "第一阶段：数据采集与画像建模（1-4月）；第二阶段：AI匹配算法开发与测试（5-8月）；第三阶段：试点运行与全市推广（9-12月）",
             "2027年8月","精准调训率≥75%，重复调训率≤5%"),
            ("建立\"训前-训中-训后\"全链条评估闭环","训前测能力短板，训中实时反馈教学质量，训后3-6个月跟踪成果转化，量化培训投入产出比",
             "干训科/市委党校/派出单位",
             "第一阶段：评估指标体系设计（1-2月）；第二阶段：评估工具开发与试点（3-7月）；第三阶段：全市推广，纳入干部考核（8-12月）",
             "2027年10月","评估闭环覆盖率≥85%，成果转化率≥50%"),
            ("统筹整合全市干部培训资源","建立市级培训资源共享平台，统一培训计划编排，消除条块分割，实现师资、课程、场地跨部门共享",
             "干训科/市委党校/各部门",
             "第一阶段：资源摸底与平台规划（1-3月）；第二阶段：共享平台建设与制度配套（4-8月）；第三阶段：试运行与全覆盖推广（9-12月）",
             "2027年12月","培训计划重复率≤8%，资源利用率提升30%"),
            ("扩容市级在线课程资源库","引进+自建双轮驱动，扩充在线课程至1000门以上，开发巴中本土治理案例课程，推行学分银行制度",
             "干训科/市委党校/网络学院",
             "第一阶段：课程需求调研与引进规划（1-2月）；第二阶段：批量引进+本土开发（3-9月）；第三阶段：学分银行上线运营（10-12月）",
             "2027年12月","在线课程≥1000门，在线学习完成率≥80%"),
            ("优化培训需求调研与反馈机制","全面落实\"三单联动\"（组织下单、干部点单、机构接单），建立培训满意度即时评价与动态调整机制",
             "干训科/各部门/县区委组织部",
             "第一阶段：需求调研流程标准化（1-3月）；第二阶段：三单联动平台开发上线（4-7月）；第三阶段：闭环运行与持续优化（8-12月）",
             "2027年8月","需求调研覆盖率≥80%，课程满意度≥85%")
        ]
    else:
        return [
            ("实施\"百案入库\"案例教学攻坚计划","围绕巴中基层治理、乡村振兴、红色文化等主题，3年开发入库100个本土化精品案例，配套教学手册",
             "市委党校教务处/各县区党校",
             "第一阶段：案例选题征集与评审（1-3月）；第二阶段：首批30个案例开发与试教（4-9月）；第三阶段：持续开发与迭代完善（10-12月）",
             "2028年6月","案例教学占比≥35%，入库案例≥100个"),
            ("推进\"名师锻造+高层次引才\"双轨师资建设","出台硕博人才引进专项政策，实施骨干教师访学计划，与省委党校等建立联合培养机制",
             "市委党校/市委组织部/市人社局",
             "第一阶段：人才政策制定与发布（1-3月）；第二阶段：首批引进+访学选派（4-8月）；第三阶段：常态化培养与考核（9-12月）",
             "2028年6月","师资硕博比≥60%，骨干教师访学率100%"),
            ("构建川陕苏区\"1+8\"红色研学标准体系","参照延安模式，对14个现有教学点标准化升级，配套统一课程包和专职教师，新建4-6个沉浸式教学点",
             "市委党校/市文广旅局/博物馆",
             "第一阶段：标准制定与点位评估（1-4月）；第二阶段：首批8个点位标准化改造（5-10月）；第三阶段：新点位建设与体系贯通（11-12月）",
             "2028年6月","标准化课程覆盖率≥85%，年均接待≥8000人次"),
            ("建设\"巴中云党校\"在线教学平台","开发直播课堂、录播点播、在线考试、学分管理一体化平台，实现5县区全覆盖",
             "市委党校/信息化部门",
             "第一阶段：平台需求分析与招标（1-3月）；第二阶段：核心模块开发与内测（4-8月）；第三阶段：试运行与全面推广（9-12月）",
             "2027年8月","在线课程≥300门，平台日活率≥50%"),
            ("推动教研一体化改革","建立科研成果转化教学激励机制，课题立项与教学案例开发挂钩，决策咨询报告一键转教学素材",
             "市委党校教务处/科研处",
             "第一阶段：教研一体化制度设计（1-3月）；第二阶段：协同平台建设与首批试点（4-8月）；第三阶段：全面推行与效果评估（9-12月）",
             "2027年12月","决策咨询采纳率≥25%，科研成果教学转化率≥40%")
        ]

def get_summary_cards(u):
    if u["duty"] == "党员教育":
        return [
            ("01","战略导向","中办《2024-2028党员教育培训规划》要求全覆盖，巴中覆盖率62%差距显著"),
            ("02","数字鸿沟","数字化平台使用率仅38%，与浙江82%相差44个百分点"),
            ("03","流动困境","5.2万流动党员纳入率48%,\"云上支部\"覆盖不足20%"),
            ("04","红色优势","川陕苏区红色资源丰富但课程化率仅22%，品牌效应未释放"),
            ("05","基础短板","32%远教站点设备老化，山区网络覆盖不足65%"),
            ("06","机遇窗口","革命老区振兴政策叠加，\"智慧红教\"建设恰逢其时")
        ]
    elif "干训科" in u["short"]:
        return [
            ("01","机制痛点","精准调训率不足40%，重复调训率18%，资源错配严重"),
            ("02","评估断裂","训后跟踪评估覆盖率仅32%，培训投入产出比低于1:1.5"),
            ("03","资源碎片","条块分割致培训计划重复率22%，学时浪费约15%"),
            ("04","供给不足","在线课程仅280门，年均在线学时仅16学时"),
            ("05","需求脱节","培训需求调研覆盖率不足35%,课程满意度低于75%"),
            ("06","转型契机","数字组工建设加速，精准调训与智慧评估时机成熟")
        ]
    else:
        return [
            ("01","教学滞后","案例教学占比仅15%，与浦东60%差距45个百分点"),
            ("02","师资薄弱","硕博比48%低于全省60%，骨干教师年均流失8%"),
            ("03","红色潜力","14个教学点标准化覆盖率36%，不及延安1/3"),
            ("04","模式单一","讲授式占比超70%，沉浸式教学尚属空白"),
            ("05","科研短板","省级以上课题年均不足8项，决策咨询采纳率<15%"),
            ("06","政策红利","革命老区振兴+党校条例修订，改革窗口期已开启")
        ]

def build_html(u):
    summaries = get_summary_cards(u)
    statuses = get_status_summary(u)
    table_rows = get_compare_table(u)
    problems = get_problems(u)
    practices = get_practices(u)
    ai_items = get_ai_items(u)
    opts = get_opts(u)
    
    # 核心摘要卡片
    summary_html = ""
    for num,tag,text in summaries:
        summary_html += '<div class="summary-card"><div class="summary-num">'+num+'</div><div class="summary-tag">'+tag+'</div><div class="summary-text">'+text+'</div></div>'
    
    # 现状指标行
    status_html = ""
    for name,val,desc in statuses:
        status_html += '<div class="status-item"><div class="status-name">'+name+'</div><div class="status-val">'+val+'</div><div class="status-desc">'+desc+'</div></div>'
    
    # 问题卡片
    problem_html = ""
    colors = {"5":"#e74c3c","4":"#e67e22","3":"#f1c40f"}
    stars_map = {"5":"★★★★★","4":"★★★★","3":"★★★"}
    for level,desc,data,src in problems:
        c = colors.get(level,"#f1c40f")
        s = stars_map.get(level,"★★★")
        problem_html += '<div class="problem-card" style="border-left:4px solid '+c+'"><div class="problem-stars" style="color:'+c+'">'+s+'</div><div class="problem-desc">'+desc+'</div><div class="problem-data">'+data+'</div><a class="problem-src" href="'+src+'" target="_blank">查看来源</a></div>'
    
    # 外省市案例
    practice_html = ""
    for city,title,data,desc,compare in practices:
        practice_html += '<div class="practice-card"><div class="practice-header"><span class="practice-city">'+city+'</span><span class="practice-title">'+title+'</span></div><div class="practice-data">'+data+'</div><div class="practice-desc">'+desc+'</div><div class="practice-compare">'+compare+'</div></div>'
    
    # AI建议时间轴
    ai_html = ""
    for icon,name,form,users,cycle,feas,detail in ai_items:
        ai_html += '<div class="ai-item"><div class="ai-icon">'+icon+'</div><div class="ai-content"><div class="ai-name">'+name+'</div><div class="ai-meta"><span class="ai-form">产品形态：'+form+'</span><span class="ai-users">目标用户：'+users+'</span><span class="ai-cycle">开发周期：'+cycle+'</span><span class="ai-feas">技术可行性：'+feas+'</span></div><div class="ai-detail">'+detail+'</div></div></div>'
    
    # 优化建议手风琴
    opt_html = ""
    for i,(title,content,resp,steps,time,kpi) in enumerate(opts):
        idx = str(i+1)
        opt_html += '<div class="opt-item"><div class="opt-header" onclick="toggleOpt(this)"><div class="opt-num">'+idx+'</div><div class="opt-title">'+title+'</div><div class="opt-arrow">▼</div></div><div class="opt-body" style="display:none"><div class="opt-content">'+content+'</div><div class="opt-resp">责任主体：'+resp+'</div><div class="opt-steps">'+steps+'</div><div class="opt-time">时间节点：'+time+'</div><div class="opt-kpi"><strong>效果评估KPI：</strong>'+kpi+'</div></div></div>'
    
    html = '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>'+u["name"]+'专项调研报告</title><style>'
    html += '*{margin:0;padding:0;box-sizing:border-box}body{font-family:"Microsoft YaHei","PingFang SC",sans-serif;background:#fff;color:#333;line-height:1.7}'
    html += '.container{max-width:1100px;margin:0 auto;padding:20px}'
    html += '.report-header{text-align:center;padding:40px 0 30px;border-bottom:3px solid #c0392b;margin-bottom:30px}'
    html += '.report-header h1{font-size:28px;color:#2c5282;margin-bottom:8px}.report-header .sub{font-size:15px;color:#666}'
    html += '.leader-section{background:linear-gradient(135deg,#c0392b 0%,#8e1a1a 50%,#2c5282 100%);border-radius:12px;padding:28px 32px;margin-bottom:32px;color:#fff;display:flex;gap:20px}'
    html += '.leader-card{flex:1;background:rgba(255,255,255,0.15);border-radius:8px;padding:18px 16px}'
    html += '.leader-card .label{font-size:12px;opacity:.8;margin-bottom:6px;letter-spacing:2px}.leader-card .value{font-size:14px;font-weight:600;line-height:1.6}'
    html += '.section{margin-bottom:36px}.section-title{font-size:22px;color:#2c5282;border-left:4px solid #c0392b;padding-left:14px;margin-bottom:20px;font-weight:700}'
    html += '.summary-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}'
    html += '.summary-card{background:#f8f9fa;border:1px solid #e2e8f0;border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:6px}'
    html += '.summary-num{font-size:24px;font-weight:800;color:#c0392b}.summary-tag{font-size:12px;color:#2c5282;font-weight:600;background:#ebf4ff;padding:2px 8px;border-radius:4px;display:inline-block;width:fit-content}'
    html += '.summary-text{font-size:13px;color:#444;line-height:1.5}'
    html += '.status-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}'
    html += '.status-item{background:#f8f9fa;border-radius:8px;padding:14px;text-align:center}'
    html += '.status-name{font-size:12px;color:#888;margin-bottom:4px}.status-val{font-size:22px;font-weight:700;color:#c0392b;margin-bottom:4px}.status-desc{font-size:11px;color:#999}'
    html += '.compare-table{width:100%;border-collapse:collapse;font-size:13px}.compare-table th{background:#2c5282;color:#fff;padding:10px 8px;text-align:left;font-weight:600}.compare-table td{padding:10px 8px;border-bottom:1px solid #e2e8f0}.compare-table tr:hover{background:#f8f9fa}'
    html += '.problem-card{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:16px;margin-bottom:12px}'
    html += '.problem-stars{font-size:14px;margin-bottom:6px}.problem-desc{font-size:15px;font-weight:600;color:#2c3e50;margin-bottom:6px}.problem-data{font-size:13px;color:#666;margin-bottom:8px}.problem-src{font-size:12px;color:#2c5282}'
    html += '.practice-card{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:18px;margin-bottom:16px}'
    html += '.practice-header{margin-bottom:10px}.practice-city{background:#2c5282;color:#fff;padding:3px 12px;border-radius:4px;font-size:13px;margin-right:10px}'
    html += '.practice-title{font-size:15px;font-weight:600;color:#2c3e50}.practice-data{font-size:13px;color:#c0392b;font-weight:600;margin-bottom:8px}'
    html += '.practice-desc{font-size:13px;color:#555;margin-bottom:10px;line-height:1.6}.practice-compare{background:#ebf8ff;border-left:3px solid #2c5282;padding:10px 14px;border-radius:4px;font-size:13px;color:#2c5282}'
    html += '.ai-timeline{position:relative;padding-left:36px}.ai-timeline::before{content:"";position:absolute;left:16px;top:0;bottom:0;width:3px;background:linear-gradient(to bottom,#c0392b,#2c5282)}'
    html += '.ai-item{position:relative;margin-bottom:22px}.ai-item::before{content:"";position:absolute;left:-24px;top:6px;width:12px;height:12px;border-radius:50%;background:#c0392b;border:2px solid #fff;box-shadow:0 0 0 3px #c0392b}'
    html += '.ai-item:nth-child(even)::before{background:#2c5282;box-shadow:0 0 0 3px #2c5282}'
    html += '.ai-icon{position:absolute;left:-28px;top:2px;font-size:14px}.ai-content{background:#f8f9fa;border-radius:8px;padding:14px 16px;border:1px solid #e2e8f0}'
    html += '.ai-name{font-size:15px;font-weight:700;color:#2c3e50;margin-bottom:6px}.ai-meta{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:6px}'
    html += '.ai-form,.ai-users,.ai-cycle,.ai-feas{font-size:11px;color:#fff;padding:2px 8px;border-radius:4px}.ai-form{background:#2c5282}.ai-users{background:#c0392b}.ai-cycle{background:#27ae60}.ai-feas{background:#8e44ad}'
    html += '.ai-detail{font-size:13px;color:#666;line-height:1.5}'
    html += '.opt-item{border:1px solid #e2e8f0;border-radius:8px;margin-bottom:10px;overflow:hidden}'
    html += '.opt-header{display:flex;align-items:center;padding:14px 16px;cursor:pointer;background:#f8f9fa;transition:background .2s}.opt-header:hover{background:#edf2f7}'
    html += '.opt-num{width:28px;height:28px;border-radius:50%;background:#c0392b;color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;margin-right:12px;flex-shrink:0}'
    html += '.opt-title{flex:1;font-size:15px;font-weight:600;color:#2c3e50}.opt-arrow{color:#999;transition:transform .3s}.opt-item.open .opt-arrow{transform:rotate(180deg)}'
    html += '.opt-body{padding:16px 16px 16px 56px;background:#fff;border-top:1px solid #e2e8f0}.opt-content{font-size:14px;color:#444;margin-bottom:10px}.opt-resp{font-size:13px;color:#2c5282;margin-bottom:8px}'
    html += '.opt-steps{font-size:13px;color:#555;margin-bottom:8px;line-height:1.7}.opt-time{font-size:13px;color:#c0392b;margin-bottom:10px;font-weight:600}'
    html += '.opt-kpi{background:#f0fff4;border:1px solid #c6f6d5;border-radius:6px;padding:10px 14px;font-size:13px;color:#276749}'
    html += '.print-btn{position:fixed;right:24px;bottom:24px;width:48px;height:48px;border-radius:50%;background:#c0392b;color:#fff;border:none;font-size:20px;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.2);z-index:999;transition:transform .2s}.print-btn:hover{transform:scale(1.1)}'
    html += '.footer{text-align:center;padding:30px 0 20px;color:#999;font-size:12px;border-top:1px solid #e2e8f0;margin-top:40px}'
    html += '@media print{.print-btn{display:none}.leader-section{-webkit-print-color-adjust:exact;print-color-adjust:exact}.container{padding:0}}'
    html += '@media(max-width:768px){.summary-grid{grid-template-columns:repeat(2,1fr)}.status-grid{grid-template-columns:repeat(2,1fr)}.leader-section{flex-direction:column}.container{padding:12px}}'
    html += '</style></head><body><div class="container">'
    
    # 报告头
    html += '<div class="report-header"><h1>'+u["name"]+'专项调研报告</h1><div class="sub">'+u["theme"]+' | '+DATE_STR+' | 基于2024-2026年公开资料整理</div></div>'
    
    # 领导速览
    html += '<div class="leader-section"><div class="leader-card"><div class="label">🔍 核心发现</div><div class="value">'+u["leader_find"]+'</div></div><div class="leader-card"><div class="label">📏 最大差距</div><div class="value">'+u["leader_gap"]+'</div></div><div class="leader-card"><div class="label">💡 首要建议</div><div class="value">'+u["leader_suggest"]+'</div></div></div>'
    
    # 壹·核心摘要
    html += '<div class="section"><div class="section-title">壹 · 核心摘要</div><div class="summary-grid">'+summary_html+'</div></div>'
    
    # 贰·上级精神与本地实践对照
    html += '<div class="section"><div class="section-title">贰 · 上级精神与本地实践对照</div>'
    html += '<div class="status-grid">'+status_html+'</div>'
    html += '<table class="compare-table" id="benchmarkTable"><thead><tr><th>指标领域</th><th>上级要求</th><th>本地现状</th><th>达标判定</th><th>本土化建议</th></tr></thead><tbody>'+table_rows+'</tbody></table></div>'
    
    # 叁·问题诊断
    html += '<div class="section"><div class="section-title">叁 · 问题诊断</div>'+problem_html+'</div>'
    
    # 肆·外省市先进做法与本地差距对比
    html += '<div class="section"><div class="section-title">肆 · 外省市先进做法与本地差距对比</div>'+practice_html+'</div>'
    
    # 伍·数智化/AI赋能专项建议
    html += '<div class="section"><div class="section-title">伍 · 数智化/AI赋能专项建议</div><div class="ai-timeline">'+ai_html+'</div></div>'
    
    # 陆·优化建议
    html += '<div class="section"><div class="section-title">陆 · 优化建议</div>'+opt_html+'</div>'
    
    # 页脚
    html += '<div class="footer">本报告数据据公开资料整理，仅供决策参考 | 生成时间：'+DATE_STR+'</div>'
    
    # 打印按钮
    html += '<button class="print-btn" onclick="window.print()" title="打印/PDF">🖨</button>'
    
    # 手风琴JS
    html += '<script>function toggleOpt(el){var item=el.parentElement;var body=item.querySelector(".opt-body");var isOpen=item.classList.contains("open");if(isOpen){item.classList.remove("open");body.style.display="none"}else{item.classList.add("open");body.style.display="block"}}</script>'
    
    html += '</div></body></html>'
    return html

# 生成3份报告
results = []
for u in UNITS:
    filename = u["id"] + TS + ".html"
    filepath = "/data/www/files/" + filename
    html_content = build_html(u)
    with open(filepath, "w", encoding="utf-8") as f:
        f.write(html_content)
    inner_url = "http://192.168.99.133:5678/" + filename
    outer_url = "https://ziyuan.cdlhyj.com/" + filename
    results.append((u["name"], filename, inner_url, outer_url, len(html_content)))

print("=" * 60)
print("巴中市3份模板B调研报告生成完成")
print("=" * 60)
for name, fn, inner, outer, size in results:
    print("\n【" + name + "】")
    print("  文件: " + fn)
    print("  大小: " + str(size) + " 字节")
    print("  内网: " + inner)
    print("  外网: " + outer)
