#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""MD2091 全预混保存 · 客户案例卡 HTML（自包含）"""
import json
import os
import sys

sys.path.insert(0, '/Users/liuxinyuan/Desktop/Hermes输出-工作类/脚本')
import brand_kit as BK  # noqa: E402

W = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
d = json.load(open(os.path.join(W, '数据/md2091_premix_cases.json'), encoding='utf-8'))
OUT = os.path.join(W, '销售分析/MD2091_全预混保存_客户案例卡_2026-10-20.html')

TAG_CLS = {'2-8℃': 'k28', '4℃': 'k4', '全预混': 'kmix', '加速': 'kacc', '正面': 'kpos',
           '反向': 'kneg', '有条件': 'kwarn', '部分正面': 'kwarn', '重点': 'kstar',
           '进行中': 'kwait', '稳定性': 'kstab'}
STATUS = ('正面', '部分正面', '有条件', '反向', '进行中')

cases = d['cases']
clients = {c['cust'] for c in cases}
n_pos = sum(1 for c in cases if ('正面' in c['tags'] or '有条件' in c['tags']) and '反向' not in c['tags'])
n_neg = sum(1 for c in cases if '反向' in c['tags'])
n_28 = sum(1 for c in cases if '2-8℃' in c['tags'])
n_mix = sum(1 for c in cases if '全预混' in c['tags'])

cards = []
for c in cases:
    tags = ''.join('<span class="tag %s">%s</span>' % (TAG_CLS.get(t, ''), t) for t in c['tags'])
    cards.append("""<article class="case" data-tags="%(tagsraw)s">
  <div class="ch"><div><div class="cust">%(cust)s</div><div class="sub">%(title)s</div></div>
    <div class="date">%(date)s</div></div>
  <div class="tags">%(tags)s</div>
  <p class="verdict">%(verdict)s</p>
  <div class="meta"><b>条件</b>%(cond)s</div>
  <blockquote>%(quote)s</blockquote>
  <div class="foot"><span>记录人：%(owner)s</span><span>活动 ID：%(wid)s</span><span class="strength">证据强度：%(strength)s</span></div>
  <div class="risk"><b>引用边界</b>%(risk)s</div>
</article>""" % {
        'tagsraw': ' '.join(c['tags']), 'cust': c['cust'], 'title': c['title'], 'date': c['date'],
        'tags': tags, 'verdict': c['verdict'], 'cond': c['cond'], 'quote': c['quote'],
        'owner': c['owner'] or '—', 'wid': c['wid'] or '—', 'strength': c['strength'], 'risk': c['risk']})

page = """<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>MD2091 全预混保存 · 客户案例卡</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#f2f5fa;color:#1b2430;font-family:-apple-system,"PingFang SC","Helvetica Neue",sans-serif;font-size:14px;line-height:1.65}
.wrap{max-width:1240px;margin:0 auto;padding:0 16px 40px}
h1{font-size:23px;margin:16px 0 4px;letter-spacing:-.3px}
.lede{color:#5f6b7a;font-size:13px;margin-bottom:14px}
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px}
.kpi{background:#fff;border:1px solid #e2e8f2;border-radius:10px;padding:11px 13px}
.kpi .t{font-size:12px;color:#5f6b7a}
.kpi b{display:block;font-size:23px;color:#1852B6;line-height:1.2;margin-top:2px}
.kpi span{font-size:11.5px;color:#8a94a3}
.bar{display:flex;flex-wrap:wrap;gap:7px;margin:6px 0 16px}
.chip{border:1px solid #d7e0ee;background:#fff;color:#33415a;border-radius:999px;padding:5px 13px;font-size:12.5px;cursor:pointer}
.chip.on{background:#1F4E79;border-color:#1F4E79;color:#fff}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.case{background:#fff;border:1px solid #e2e8f2;border-radius:11px;padding:13px 15px;display:flex;flex-direction:column}
.ch{display:flex;justify-content:space-between;gap:10px;align-items:flex-start}
.cust{font-size:15px;font-weight:800;color:#0E2E63}
.sub{font-size:12.2px;color:#5f6b7a;margin-top:2px}
.date{font-size:12px;color:#8a94a3;white-space:nowrap;font-variant-numeric:tabular-nums}
.tags{margin:8px 0 6px;display:flex;flex-wrap:wrap;gap:5px}
.tag{font-size:10.8px;font-weight:700;border-radius:4px;padding:1.5px 7px;background:#EEF1F6;color:#4b5768}
.k28{background:#FDE7E7;color:#A42020}.k4{background:#FDEBE0;color:#9A4A12}
.kmix{background:#E4EEFB;color:#14497F}.kacc{background:#E8F0FE;color:#1B4EA8}
.kpos{background:#E4F5EA;color:#1B7A43}.kneg{background:#FBE3E3;color:#8C1D1D}
.kwarn{background:#FFF3DA;color:#8A5A00}.kstar{background:#1F4E79;color:#fff}
.kwait{background:#EFEFEF;color:#5c5c5c}.kstab{background:#E9F1F7;color:#245A7A}
.verdict{margin:4px 0 8px;font-size:13.6px;font-weight:600;color:#22303f}
.meta{font-size:12.4px;color:#44505f;background:#F7F9FC;border-radius:7px;padding:6px 9px;margin-bottom:8px}
.meta b{color:#1852B6;margin-right:6px}
blockquote{margin:0 0 9px;padding:8px 11px;border-left:3px solid #B9CCE6;background:#FAFBFD;color:#3b4757;font-size:12.3px;line-height:1.62;border-radius:0 7px 7px 0}
.foot{display:flex;flex-wrap:wrap;gap:12px;font-size:11.4px;color:#7b8797;margin-top:auto}
.strength{color:#1852B6;font-weight:600}
.risk{margin-top:8px;font-size:12.1px;color:#7a5211;background:#FFF9EC;border:1px solid #F3E3BF;border-radius:7px;padding:6px 9px}
.risk b{color:#8A5A00;margin-right:6px}
.sec{margin-top:20px;background:#fff;border:1px solid #e2e8f2;border-radius:11px;padding:14px 16px}
.sec h2{font-size:15.5px;margin:0 0 8px;padding-left:9px;border-left:3px solid #1F4E79}
.sec ol,.sec ul{margin:6px 0 0 20px;padding:0}
.sec li{margin-bottom:7px;font-size:13px}
.note{background:#FFF6E5;border:1px solid #F3D9A6;border-radius:8px;padding:10px 12px;font-size:12.6px;margin-top:10px}
.empty{display:none;padding:24px;text-align:center;color:#8a94a3;font-size:13px}
@media(max-width:860px){.grid{grid-template-columns:1fr}.kpis{grid-template-columns:1fr 1fr}h1{font-size:20px}}
@media(max-width:900px){.bior-tagwrap{display:none!important}}
.case,.meta,.foot,blockquote{min-width:0;overflow-wrap:anywhere}
.ch{flex-wrap:wrap}
</style></head><body><div class="wrap">
<h1>MD2091 · 全预混保存客户案例卡</h1>
<div class="lede">口径：仅收录活动记录里明确提到 MD2091 且涉及全预混 / 保存温度 / 加速的条目；每张卡附原文、记录人与活动 ID，可回溯。数据源覆盖 2026-07 上旬至 2026-10-20。</div>

<div class="kpis">
  <div class="kpi"><div class="t">案例条目</div><b>%(n)s</b><span>涉及 %(nc)s 家客户</span></div>
  <div class="kpi"><div class="t">正面 / 有条件正面</div><b>%(npos)s</b><span>可用于对外沟通</span></div>
  <div class="kpi"><div class="t">全预混相关</div><b>%(nmix)s</b><span>含稳定性验证</span></div>
  <div class="kpi"><div class="t">2–8℃ 条件</div><b>%(n28)s</b><span>条件未写死，需补证</span></div>
</div>

<div class="bar">
  <button class="chip on" data-f="all">全部 %(n)s</button>
  <button class="chip" data-f="2-8℃">2–8℃ %(n28)s</button>
  <button class="chip" data-f="全预混">全预混 %(nmix)s</button>
  <button class="chip" data-f="加速">加速</button>
  <button class="chip" data-f="正面">正面</button>
  <button class="chip" data-f="反向">反向 %(nneg)s</button>
  <button class="chip" data-f="进行中">进行中</button>
</div>

<div class="grid" id="grid">%(cards)s</div>
<div class="empty" id="empty">该筛选下暂无案例</div>

<div class="sec"><h2>推荐给海尔施分子诊断流水线项目组的三个要点</h2>
<ol>
<li><b>同场景已有平行对比数据</b>：海尔施痰液提取全预混项目三款体系同批测试，MD2091 效果最好，000811 出现大肠杆菌假阳、020314 扩增曲线较差；客户已同意继续测 MD2091。这是目前最贴近流水线全预混场景的案例。</li>
<li><b>全预混形态在多家客户走通初筛</b>：正大康瑞（细小，MD2091-001102/092402 两轮均为最优，换引探后通过 37℃ 3D/7D 加速）、冠牧（DNA 预混初筛 ok）、圣湘（000811-DB 即时扩增符合需求）。可用于说明“全预混形态不是个例”。</li>
<li><b>加速数据可作为佐证但要限定通道与浓度</b>：正大康瑞 37℃ 7D 通过；卓诚惠生 CY5 通道室温 3d / 37℃ 1d 无差异，但 AF405 低浓度出现 Rn 下降。对流水线项目应主动说明多色与低浓度场景需单独验证。</li>
</ol>
<div class="note"><b>必须同时告知客户的边界</b>：① 目前没有任何一家提供“2–8℃ 全预混 + 明确时长 + 可引用数据”，天隆那条是客户有 2–8℃ 要求、MD2091 表现较好，但记录未写明是同一实验；② 青岛嘉智 4℃ 全预混一个月的终端要求下，MD2091-001102 临界值检出不如 095203；③ 圣湘 000811 在加速后出现更容易起线的问题。这三条不主动讲，客户一旦自己测出来会反噬案例可信度。</div></div>

<div class="sec"><h2>要补的一个数据缺口（建议本周启动）</h2>
<ul>
<li><b>验证设计</b>：MD2091 全预混（含模板）× 2–8℃ 与 4℃ 双条件 × 0/7/14/28 天，另设室温 4h、37℃ 3d 对照。</li>
<li><b>观测指标</b>：Ct 偏移、荧光值衰减比例、低浓度检出下限（1 copies/μL 梯度）。</li>
<li><b>主责 / 验收</b>：技术支持出数据，产品复核，刘新元验收；产出可直接替换本页“待补证”标注。</li>
</ul></div>

<div class="sec"><h2>口径与边界</h2>
<div class="note">
<ul style="margin:0 0 0 18px">
<li>收录规则：活动库里提到 MD2091，且正文涉及全预混 / 保存温度 / 加速 / 稳定性；同客户同日多条记录时取含 MD2091 的那条。</li>
<li>原文为活动记录逐字摘录（已去 HTML 与图片链接），未做改写；判断与“证据强度”为二次归纳，与原文分列。</li>
<li>覆盖窗口：2026-07 上旬至 2026-10-20 的飞书活动库；更早月份在月报档，未纳入本版。书面测试反馈库为空，ERP 订单备注不区分保存条件。</li>
<li>说明书口径：−20℃ 长期保存，4℃ 可保存 3 个月，避免反复冻融——这是产品本身指标，不等同于“配好全预混后”的稳定性。</li>
</ul></div></div>
%(footer)s
</div>
<script>
(function(){
  var grid=document.getElementById('grid'), cards=[].slice.call(grid.querySelectorAll('.case'));
  var chips=[].slice.call(document.querySelectorAll('.chip')), empty=document.getElementById('empty');
  chips.forEach(function(ch){
    ch.addEventListener('click', function(){
      chips.forEach(function(c){ c.classList.remove('on'); });
      ch.classList.add('on');
      var f=ch.getAttribute('data-f'), shown=0;
      cards.forEach(function(card){
        var tags=(card.getAttribute('data-tags')||'').split(' ');
        var ok = (f==='all') || tags.indexOf(f)>=0;
        card.style.display = ok ? '' : 'none';
        if(ok) shown++;
      });
      empty.style.display = shown ? 'none' : 'block';
    });
  });
})();
</script>
</body></html>""" % {
    'n': len(cases), 'nc': len(clients), 'npos': n_pos, 'nmix': n_mix, 'n28': n_28, 'nneg': n_neg,
    'cards': '\n'.join(cards), 'footer': '__F__',
}
page = BK.inject(page, theme='dark', tag='MD2091 · 全预混保存案例',
                 footer_extra='内部资料 · 客户案例库 ｜ 原文可回溯至飞书活动')
page = page.replace('__F__', '')
open(OUT, 'w', encoding='utf-8').write(page)
print('✅', OUT, '%.0f KB' % (len(page.encode()) / 1024))
