{"token":"e2c236cc-df0b-4f6b-ab16-a15e7caad3b0","title":"供应商合作案例","dashboard_str":"{\"title\":\"供应商合作案例\",\"viewInfos\":[{\"file_name\":\"供应商管理_虚拟数据100条.xlsx\",\"file_url\":\"https://excelup.kyou.ltd/uploads/2lrac31mny36/file-59867ae9-7101-42.xlsx\",\"id\":20130,\"hashId\":\"e39b33bdb8aa10d2dee6fe6c1fc71130\"}],\"query\":\"原样输出该html,不要有任何修改:\\n\u003c!DOCTYPE html\u003e\\n\u003chtml lang=\\\"zh-CN\\\"\u003e\\n\u003chead\u003e\\n\u003cmeta charset=\\\"UTF-8\\\"\u003e\\n\u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"\u003e\\n\u003ctitle\u003e供应商合作价值评估看板\u003c/title\u003e\\n\u003clink rel=\\\"stylesheet\\\" href=\\\"https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css\\\"\u003e\\n\u003cscript src=\\\"https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js\\\"\u003e\u003c/script\u003e\\n\u003cstyle\u003e\\n :root{\\n --brand:#2f6fed;\\n --brand-deep:#1c4ed8;\\n --navy:#0f2742;\\n --navy-2:#16345c;\\n --teal:#0ea5e9;\\n --growth:#12b981;\\n --warn:#f5a524;\\n --danger:#e5484d;\\n --violet:#8b5cf6;\\n --bg:#eef2f9;\\n --card:#ffffff;\\n --text:#12233d;\\n --muted:#66758c;\\n --line:#e3eaf5;\\n --radius:16px;\\n --radius-sm:10px;\\n --shadow-sm:0 1px 2px rgba(18,35,61,.05);\\n --shadow:0 6px 24px rgba(18,35,61,.07);\\n --shadow-lg:0 18px 44px rgba(18,35,61,.14);\\n --grad-brand:linear-gradient(135deg,#2f6fed,#0ea5e9);\\n --grad-hero:linear-gradient(120deg,#0a1e38 0%,#12305c 45%,#1c4ed8 100%);\\n }\\n html,body{\\n background:\\n radial-gradient(1100px 460px at 88% -8%, rgba(47,111,237,.10), transparent 60%),\\n radial-gradient(900px 420px at -8% 4%, rgba(18,185,129,.07), transparent 55%),\\n var(--bg);\\n color:var(--text);\\n font-family:-apple-system,BlinkMacSystemFont,\\\"Segoe UI\\\",\\\"PingFang SC\\\",\\\"Hiragino Sans GB\\\",\\\"Microsoft YaHei\\\",sans-serif;\\n -webkit-font-smoothing:antialiased;\\n }\\n .num{font-variant-numeric:tabular-nums;}\\n .card{border-radius:var(--radius);box-shadow:var(--shadow-sm),var(--shadow);border:1px solid var(--line);background:var(--card);transition:transform .22s ease, box-shadow .22s ease;}\\n .card:hover{box-shadow:var(--shadow-lg);transform:translateY(-2px);}\\n .card.plain:hover{transform:none;}\\n\\n /* ===== 页头 ===== */\\n .hero-head{\\n position:relative;overflow:hidden;color:#fff;\\n background:var(--grad-hero);\\n padding:34px 0 30px;\\n border-bottom:3px solid transparent;\\n border-image:linear-gradient(90deg,#2f6fed,#12b981,#f5a524) 1;\\n }\\n .hero-head::before{\\n content:\\\"\\\";position:absolute;inset:0;pointer-events:none;\\n background-image:\\n linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),\\n linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);\\n background-size:44px 44px;\\n mask-image:radial-gradient(ellipse at 70% 0%, #000 20%, transparent 75%);\\n }\\n .hero-head::after{\\n content:\\\"\\\";position:absolute;right:-120px;top:-160px;width:420px;height:420px;border-radius:50%;\\n background:radial-gradient(circle, rgba(47,111,237,.45), transparent 65%);\\n pointer-events:none;\\n }\\n .hero-inner{display:flex;align-items:center;gap:18px;position:relative;z-index:1;}\\n .brand-badge{\\n flex:0 0 auto;width:58px;height:58px;border-radius:16px;display:flex;align-items:center;justify-content:center;\\n background:linear-gradient(135deg,#2f6fed,#0ea5e9);box-shadow:0 10px 26px rgba(47,111,237,.45), inset 0 1px 0 rgba(255,255,255,.35);\\n }\\n .brand-badge svg{width:30px;height:30px;stroke:#fff;}\\n .head-kicker{font-size:.72rem;font-weight:700;letter-spacing:3px;color:#8fb6ff;text-transform:uppercase;margin-bottom:4px;}\\n .head-title{font-size:1.7rem;font-weight:800;letter-spacing:.6px;margin:0;line-height:1.25;}\\n .head-title em{font-style:normal;background:linear-gradient(90deg,#7ab8ff,#4ade80);-webkit-background-clip:text;background-clip:text;color:transparent;}\\n .head-sub{font-size:.86rem;color:#b9cdf5;font-weight:400;margin-top:5px;letter-spacing:.3px;}\\n .head-meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;position:relative;z-index:1;}\\n .head-chip{\\n display:inline-flex;align-items:center;gap:7px;font-size:.76rem;color:#d7e4ff;\\n background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.14);\\n border-radius:999px;padding:5px 13px;backdrop-filter:blur(4px);\\n }\\n .head-chip svg{width:13px;height:13px;stroke:#7ab8ff;}\\n .head-chip b{color:#fff;font-weight:700;}\\n\\n /* ===== 吸顶筛选栏 ===== */\\n .filter-shell{position:sticky;top:0;z-index:60;background:rgba(238,242,249,.86);backdrop-filter:blur(12px);}\\n .filter-shell .section{padding-top:2rem;}\\n .filter-card{box-shadow:var(--shadow);border:1px solid rgba(255,255,255,.7);}\\n .filter-title{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:700;color:var(--navy);}\\n .filter-title svg{width:15px;height:15px;stroke:var(--brand);}\\n .filter-bar .label{font-size:.72rem;color:var(--muted);font-weight:700;letter-spacing:1px;margin-bottom:5px;}\\n .filter-bar .select select,.filter-bar .input{\\n border-radius:10px;border:1px solid #d6e0f0;background:#fff;color:var(--text);\\n font-size:.85rem;font-weight:500;box-shadow:0 1px 2px rgba(18,35,61,.04);transition:border-color .18s, box-shadow .18s;\\n }\\n .filter-bar .select select:focus,.filter-bar .input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(47,111,237,.14);}\\n .btn-reset{\\n border-radius:10px;border:1px solid #d6e0f0;background:#fff;color:var(--navy);font-weight:600;font-size:.85rem;\\n display:inline-flex;align-items:center;justify-content:center;gap:7px;height:2.5em;\\n transition:all .18s;\\n }\\n .btn-reset svg{width:14px;height:14px;stroke:var(--muted);}\\n .btn-reset:hover{border-color:var(--brand);color:var(--brand);background:#f4f8ff;}\\n .btn-reset:hover svg{stroke:var(--brand);}\\n\\n /* ===== KPI 卡片 ===== */\\n .kpi-card{display:flex;align-items:center;gap:14px;padding:16px 16px;position:relative;overflow:hidden;height:100%;}\\n .kpi-card::after{\\n content:\\\"\\\";position:absolute;right:-30px;top:-30px;width:110px;height:110px;border-radius:50%;\\n background:radial-gradient(circle, var(--kpi-soft), transparent 70%);pointer-events:none;\\n }\\n .kpi-icon{\\n flex:0 0 auto;width:46px;height:46px;border-radius:13px;display:flex;align-items:center;justify-content:center;\\n background:var(--kpi-soft);color:var(--kpi);box-shadow:inset 0 0 0 1px var(--kpi-border);\\n }\\n .kpi-icon svg{width:22px;height:22px;stroke:var(--kpi);}\\n .kpi-body{min-width:0;position:relative;z-index:1;}\\n .kpi-label{font-size:.74rem;color:var(--muted);font-weight:700;letter-spacing:1.2px;}\\n .kpi-value{font-size:1.78rem;font-weight:800;line-height:1.2;color:var(--navy);margin-top:2px;letter-spacing:-.5px;}\\n .kpi-sub{font-size:.74rem;color:var(--muted);margin-top:4px;font-weight:500;}\\n\\n /* ===== 图表卡片 ===== */\\n .chart-card{min-height:0;}\\n .card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:15px 18px 12px;border-bottom:1px solid var(--line);}\\n .card-head-left{display:flex;align-items:center;gap:11px;min-width:0;}\\n .card-ico{\\n flex:0 0 auto;width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;\\n background:linear-gradient(135deg, rgba(47,111,237,.12), rgba(14,165,233,.10));\\n box-shadow:inset 0 0 0 1px rgba(47,111,237,.16);\\n }\\n .card-ico svg{width:17px;height:17px;stroke:var(--brand);}\\n .card-title{font-size:.96rem;font-weight:800;color:var(--navy);letter-spacing:.2px;line-height:1.2;}\\n .card-sub{font-size:.72rem;color:var(--muted);margin-top:2px;font-weight:500;}\\n .card-tag{font-size:.7rem;font-weight:700;color:#5b6b85;background:#f1f5fd;border:1px solid #e3eaf5;border-radius:999px;padding:4px 10px;white-space:nowrap;}\\n .card-body{padding:14px 16px 10px;}\\n .chart-box{width:100%;}\\n .matrix-col{display:flex;}\\n .matrix-col .chart-card{flex:1;display:flex;flex-direction:column;width:100%;}\\n .matrix-col .card-head{padding:10px 18px 8px;}\\n .matrix-col .card-body{flex:1;display:flex;flex-direction:column;padding:2px 16px 6px;}\\n .matrix-chart{flex:1;min-height:340px;}\\n\\n /* ===== 标签 ===== */\\n .tag{font-weight:700;border-radius:999px;padding:2px 10px;font-size:.72rem;border:none;}\\n .t-green{background:rgba(18,185,129,.13);color:#0b8f63;}\\n .t-amber{background:rgba(245,165,36,.15);color:#b26a05;}\\n .t-red{background:rgba(229,72,77,.13);color:#c53339;}\\n .t-blue{background:rgba(47,111,237,.13);color:#1d55d0;}\\n .t-violet{background:rgba(139,92,246,.15);color:#6d3fd6;}\\n .t-gray{background:rgba(102,117,140,.13);color:#56647a;}\\n .t-cyan{background:rgba(14,165,233,.13);color:#0a7fb8;}\\n\\n /* ===== 明细表 ===== */\\n .table-wrap{overflow-x:auto;max-height:540px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:#c6d2e8 transparent;}\\n .table-wrap::-webkit-scrollbar{width:8px;height:8px;}\\n .table-wrap::-webkit-scrollbar-thumb{background:#c6d2e8;border-radius:8px;}\\n .table{font-size:.8rem;color:var(--text);border-collapse:separate;border-spacing:0;}\\n .table thead th{\\n position:sticky;top:0;z-index:2;background:#f4f8ff;color:#33507a;font-weight:700;white-space:nowrap;\\n cursor:pointer;user-select:none;border-bottom:2px solid #dbe6f7;padding:10px 12px;font-size:.74rem;letter-spacing:.4px;\\n }\\n .table thead th:hover{color:var(--brand);background:#eef5ff;}\\n .table td{white-space:nowrap;vertical-align:middle;padding:9px 12px;border-bottom:1px solid #f0f4fa;}\\n .table tbody tr{cursor:pointer;transition:background .15s;}\\n .table tbody tr:hover{background:#f3f7ff;}\\n .table tbody tr:nth-child(even){background:#fafcff;}\\n .table tbody tr:nth-child(even):hover{background:#f3f7ff;}\\n .supplier-cell b{color:var(--navy);font-weight:700;}\\n .supplier-id{color:#9aa8c0;font-size:.68rem;letter-spacing:.5px;}\\n .vi-cell{color:var(--brand-deep);font-weight:800;font-size:.88rem;}\\n .score-cell{font-weight:700;color:#33507a;}\\n\\n /* ===== 空状态 / 页脚 ===== */\\n .empty-note{display:none;text-align:center;color:var(--muted);padding:64px 10px;font-size:.95rem;}\\n .empty-note svg{width:38px;height:38px;stroke:#b6c4dc;margin-bottom:8px;}\\n .footer-note{color:#8b99b2;font-size:.76rem;text-align:center;padding:20px 0 30px;letter-spacing:.4px;}\\n\\n /* ===== 入场动画 ===== */\\n @keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\\n .kpi-card{animation:rise .5s ease both;}\\n .chart-card{animation:rise .55s ease both;}\\n .kpi-card:nth-child(2){animation-delay:.04s}.kpi-card:nth-child(3){animation-delay:.08s}\\n .kpi-card:nth-child(4){animation-delay:.12s}.kpi-card:nth-child(5){animation-delay:.16s}\\n .kpi-card:nth-child(6){animation-delay:.2s}\\n\\n @media screen and (max-width:768px){\\n .head-title{font-size:1.3rem;}\\n .head-sub{font-size:.78rem;}\\n .hero-head{padding:24px 0;}\\n .kpi-value{font-size:1.45rem;}\\n .card-head{flex-wrap:wrap;}\\n }\\n\u003c/style\u003e\\n\u003c/head\u003e\\n\u003cbody\u003e\\n\\n\u003c!-- 页头 --\u003e\\n\u003cheader class=\\\"hero-head\\\" block_id=\\\"page-title\\\"\u003e\\n \u003cdiv class=\\\"container\\\"\u003e\\n \u003cdiv class=\\\"hero-inner\\\"\u003e\\n \u003cdiv class=\\\"brand-badge\\\"\u003e\\n \u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\\n \u003cpath d=\\\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\\\"/\u003e\u003ccircle cx=\\\"9\\\" cy=\\\"7\\\" r=\\\"4\\\"/\u003e\\n \u003cpath d=\\\"M23 21v-2a4 4 0 0 0-3-3.87\\\"/\u003e\u003cpath d=\\\"M16 3.13a4 4 0 0 1 0 7.75\\\"/\u003e\\n \u003c/svg\u003e\\n \u003c/div\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"head-kicker\\\"\u003eSupplier Intelligence · 供应商智能评估\u003c/div\u003e\\n \u003ch1 class=\\\"head-title\\\"\u003e供应商合作价值\u003cem\u003e评估看板\u003c/em\u003e\u003c/h1\u003e\\n \u003cp class=\\\"head-sub\\\"\u003e多维量化合作价值 · 甄选优质伙伴 · 驱动供应链共赢\u003c/p\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"head-meta\\\" id=\\\"header-meta\\\"\u003e\\n \u003cspan class=\\\"head-chip\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003crect x=\\\"3\\\" y=\\\"4\\\" width=\\\"18\\\" height=\\\"18\\\" rx=\\\"2\\\" ry=\\\"2\\\"/\u003e\u003cline x1=\\\"16\\\" y1=\\\"2\\\" x2=\\\"16\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"8\\\" y1=\\\"2\\\" x2=\\\"8\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"10\\\" x2=\\\"21\\\" y2=\\\"10\\\"/\u003e\u003c/svg\u003e数据加载中…\u003c/span\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\u003c/header\u003e\\n\\n\u003c!-- 吸顶筛选栏 --\u003e\\n\u003cdiv class=\\\"filter-shell\\\"\u003e\\n \u003csection class=\\\"section pt-4 pb-4\\\" block_id=\\\"filter-bar\\\"\u003e\\n \u003cdiv class=\\\"container\\\"\u003e\\n \u003cdiv class=\\\"card filter-card plain\\\"\u003e\\n \u003cdiv class=\\\"card-content py-4\\\"\u003e\\n \u003cdiv class=\\\"filter-title mb-3\\\"\u003e\\n \u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cline x1=\\\"4\\\" y1=\\\"21\\\" x2=\\\"4\\\" y2=\\\"14\\\"/\u003e\u003cline x1=\\\"4\\\" y1=\\\"10\\\" x2=\\\"4\\\" y2=\\\"3\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"21\\\" x2=\\\"12\\\" y2=\\\"12\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"8\\\" x2=\\\"12\\\" y2=\\\"3\\\"/\u003e\u003cline x1=\\\"20\\\" y1=\\\"21\\\" x2=\\\"20\\\" y2=\\\"16\\\"/\u003e\u003cline x1=\\\"20\\\" y1=\\\"12\\\" x2=\\\"20\\\" y2=\\\"3\\\"/\u003e\u003cline x1=\\\"1\\\" y1=\\\"14\\\" x2=\\\"7\\\" y2=\\\"14\\\"/\u003e\u003cline x1=\\\"9\\\" y1=\\\"8\\\" x2=\\\"15\\\" y2=\\\"8\\\"/\u003e\u003cline x1=\\\"17\\\" y1=\\\"16\\\" x2=\\\"23\\\" y2=\\\"16\\\"/\u003e\u003c/svg\u003e\\n 多维筛选 · 联动分析\\n \u003c/div\u003e\\n \u003cdiv class=\\\"columns is-multiline is-variable is-3 filter-bar\\\"\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-category\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e品类 CATEGORY\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cdiv class=\\\"select is-fullwidth\\\"\u003e\u003cselect id=\\\"sel-category\\\"\u003e\u003coption value=\\\"全部\\\"\u003e全部品类\u003c/option\u003e\u003c/select\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-region\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e区域 REGION\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cdiv class=\\\"select is-fullwidth\\\"\u003e\u003cselect id=\\\"sel-region\\\"\u003e\u003coption value=\\\"全部\\\"\u003e全部区域\u003c/option\u003e\u003c/select\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-risk\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e风险等级 RISK\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cdiv class=\\\"select is-fullwidth\\\"\u003e\u003cselect id=\\\"sel-risk\\\"\u003e\u003coption value=\\\"全部\\\"\u003e全部风险\u003c/option\u003e\u003c/select\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-status\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e合作状态 STATUS\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cdiv class=\\\"select is-fullwidth\\\"\u003e\u003cselect id=\\\"sel-status\\\"\u003e\u003coption value=\\\"全部\\\"\u003e全部状态\u003c/option\u003e\u003c/select\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-action\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e建议动作 ACTION\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cdiv class=\\\"select is-fullwidth\\\"\u003e\u003cselect id=\\\"sel-action\\\"\u003e\u003coption value=\\\"全部\\\"\u003e全部动作\u003c/option\u003e\u003c/select\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-3-tablet\\\" block_id=\\\"filter-reset\\\"\u003e\\n \u003clabel class=\\\"label\\\"\u003e\u0026nbsp;\u003c/label\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cbutton class=\\\"button btn-reset is-fullwidth\\\" id=\\\"btn-reset\\\"\u003e\\n \u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolyline points=\\\"1 4 1 10 7 10\\\"/\u003e\u003cpath d=\\\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\\\"/\u003e\u003c/svg\u003e\\n 重置筛选\\n \u003c/button\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/section\u003e\\n\u003c/div\u003e\\n\\n\u003c!-- KPI 卡片 --\u003e\\n\u003csection class=\\\"section pt-4 pb-4\\\"\u003e\\n \u003cdiv class=\\\"container\\\"\u003e\\n \u003cdiv class=\\\"columns is-multiline is-variable is-3\\\"\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-count\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#2f6fed;--kpi-soft:rgba(47,111,237,.12);--kpi-border:rgba(47,111,237,.22);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\\\"/\u003e\u003cpolyline points=\\\"14 2 14 8 20 8\\\"/\u003e\u003cline x1=\\\"16\\\" y1=\\\"13\\\" x2=\\\"8\\\" y2=\\\"13\\\"/\u003e\u003cline x1=\\\"16\\\" y1=\\\"17\\\" x2=\\\"8\\\" y2=\\\"17\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e供应商记录数\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-count\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-count-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-amt\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#0ea5e9;--kpi-soft:rgba(14,165,233,.13);--kpi-border:rgba(14,165,233,.24);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cline x1=\\\"12\\\" y1=\\\"1\\\" x2=\\\"12\\\" y2=\\\"23\\\"/\u003e\u003cpath d=\\\"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e年度采购总额 (万元)\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-amt\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-amt-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-value\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#12b981;--kpi-soft:rgba(18,185,129,.13);--kpi-border:rgba(18,185,129,.24);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolyline points=\\\"23 6 13.5 15.5 8.5 10.5 1 18\\\"/\u003e\u003cpolyline points=\\\"17 6 23 6 23 12\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e平均合作价值指数\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-value\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-value-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-score\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#8b5cf6;--kpi-soft:rgba(139,92,246,.14);--kpi-border:rgba(139,92,246,.24);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolygon points=\\\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e平均综合评分\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-score\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-score-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-otd\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#06b6d4;--kpi-soft:rgba(6,182,212,.13);--kpi-border:rgba(6,182,212,.24);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"12\\\" r=\\\"10\\\"/\u003e\u003cpolyline points=\\\"12 6 12 12 16 14\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e平均准时交付率\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-otd\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-otd-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-mobile is-4\\\" block_id=\\\"kpi-risk\\\"\u003e\\n \u003cdiv class=\\\"card kpi-card\\\" style=\\\"--kpi:#e5484d;--kpi-soft:rgba(229,72,77,.12);--kpi-border:rgba(229,72,77,.22);\\\"\u003e\\n \u003cdiv class=\\\"kpi-icon\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"9\\\" x2=\\\"12\\\" y2=\\\"13\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"17\\\" x2=\\\"12.01\\\" y2=\\\"17\\\"/\u003e\u003c/svg\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-body\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e高风险供应商占比\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value num\\\" id=\\\"kpi-risk\\\"\u003e—\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-sub\\\" id=\\\"kpi-risk-sub\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\u003c/section\u003e\\n\\n\u003c!-- 核心图表区 --\u003e\\n\u003csection class=\\\"section pt-4\\\"\u003e\\n \u003cdiv class=\\\"container\\\"\u003e\\n \u003c!-- 第一行: 价值矩阵 + 风险/状态 --\u003e\\n \u003cdiv class=\\\"columns is-multiline\\\"\u003e\\n \u003cdiv class=\\\"column is-12 is-8-desktop matrix-col\\\" block_id=\\\"chart-matrix\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"12\\\" r=\\\"10\\\"/\u003e\u003cline x1=\\\"22\\\" y1=\\\"12\\\" x2=\\\"18\\\" y2=\\\"12\\\"/\u003e\u003cline x1=\\\"6\\\" y1=\\\"12\\\" x2=\\\"2\\\" y2=\\\"12\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"6\\\" x2=\\\"12\\\" y2=\\\"2\\\"/\u003e\u003cline x1=\\\"12\\\" y1=\\\"22\\\" x2=\\\"12\\\" y2=\\\"18\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e供应商价值矩阵\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e采购规模 × 合作价值指数 · 定位优质合作伙伴\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cspan class=\\\"card-tag\\\"\u003e气泡 = 订单量 · 颜色 = 风险等级\u003c/span\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\\n \u003cdiv id=\\\"chart-matrix-box\\\" class=\\\"chart-box matrix-chart\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-12 is-4-desktop\\\"\u003e\\n \u003cdiv class=\\\"columns is-multiline is-gapless\\\"\u003e\\n \u003cdiv class=\\\"column is-12\\\" block_id=\\\"chart-risk\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e风险等级分布\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e供应风险结构透视\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-risk-box\\\" class=\\\"chart-box\\\" style=\\\"height:192px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-12 mt-3\\\" block_id=\\\"chart-status\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\\\"/\u003e\u003ccircle cx=\\\"9\\\" cy=\\\"7\\\" r=\\\"4\\\"/\u003e\u003cpath d=\\\"M23 21v-2a4 4 0 0 0-3-3.87\\\"/\u003e\u003cpath d=\\\"M16 3.13a4 4 0 0 1 0 7.75\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e合作状态构成\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e伙伴关系层级分布\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-status-box\\\" class=\\\"chart-box\\\" style=\\\"height:192px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- 第二行: Top10 + 品类 --\u003e\\n \u003cdiv class=\\\"columns is-multiline mt-0\\\"\u003e\\n \u003cdiv class=\\\"column is-12 is-6-desktop\\\" block_id=\\\"chart-top10\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"8\\\" r=\\\"7\\\"/\u003e\u003cpolyline points=\\\"8.21 13.89 7 23 12 20 17 23 15.79 13.88\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e合作价值指数 Top 10\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e头部高价值合作伙伴\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cspan class=\\\"card-tag\\\"\u003e按价值指数降序\u003c/span\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-top10-box\\\" class=\\\"chart-box\\\" style=\\\"height:350px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-12 is-6-desktop\\\" block_id=\\\"chart-category\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolygon points=\\\"12 2 2 7 12 12 22 7 12 2\\\"/\u003e\u003cpolyline points=\\\"2 17 12 22 22 17\\\"/\u003e\u003cpolyline points=\\\"2 12 12 17 22 12\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e品类采购规模与平均价值指数\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e按品类审视投入与回报\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-category-box\\\" class=\\\"chart-box\\\" style=\\\"height:350px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- 第三行: 区域 + 绩效 + 建议动作 --\u003e\\n \u003cdiv class=\\\"columns is-multiline mt-0\\\"\u003e\\n \u003cdiv class=\\\"column is-12 is-4-desktop\\\" block_id=\\\"chart-region\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\\\"/\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"10\\\" r=\\\"3\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e区域采购额分布\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e供应链地理布局\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-region-box\\\" class=\\\"chart-box\\\" style=\\\"height:320px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-12 is-4-desktop\\\" block_id=\\\"chart-perf\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolyline points=\\\"22 12 18 12 15 21 9 3 6 12 2 12\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e交付与质量绩效矩阵\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e执行力 × 品质保障\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cspan class=\\\"card-tag\\\"\u003e气泡 = 采购额\u003c/span\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-perf-box\\\" class=\\\"chart-box\\\" style=\\\"height:320px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-12 is-4-desktop\\\" block_id=\\\"chart-action\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"12\\\" r=\\\"10\\\"/\u003e\u003cpolygon points=\\\"16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e建议动作分布\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e下一步合作策略\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body\\\"\u003e\u003cdiv id=\\\"chart-action-box\\\" class=\\\"chart-box\\\" style=\\\"height:320px;\\\"\u003e\u003c/div\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- 明细表 --\u003e\\n \u003cdiv class=\\\"columns is-multiline mt-0\\\"\u003e\\n \u003cdiv class=\\\"column is-12\\\" block_id=\\\"table-suppliers\\\"\u003e\\n \u003cdiv class=\\\"card chart-card\\\"\u003e\\n \u003cdiv class=\\\"card-head\\\"\u003e\\n \u003cdiv class=\\\"card-head-left\\\"\u003e\\n \u003cspan class=\\\"card-ico\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cline x1=\\\"8\\\" y1=\\\"6\\\" x2=\\\"21\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"8\\\" y1=\\\"12\\\" x2=\\\"21\\\" y2=\\\"12\\\"/\u003e\u003cline x1=\\\"8\\\" y1=\\\"18\\\" x2=\\\"21\\\" y2=\\\"18\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"6\\\" x2=\\\"3.01\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"12\\\" x2=\\\"3.01\\\" y2=\\\"12\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"18\\\" x2=\\\"3.01\\\" y2=\\\"18\\\"/\u003e\u003c/svg\u003e\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003cdiv class=\\\"card-title\\\"\u003e供应商明细清单 \u003cspan class=\\\"tag t-blue ml-2\\\" id=\\\"table-count-tag\\\"\u003e0 条\u003c/span\u003e\u003c/div\u003e\\n \u003cdiv class=\\\"card-sub\\\"\u003e点击表头排序 · 支持关键词检索\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"control\\\"\u003e\\n \u003cinput class=\\\"input\\\" id=\\\"search-supplier\\\" type=\\\"text\\\" placeholder=\\\"搜索供应商 / ID / 品类\\\" style=\\\"width:230px;\\\"\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"card-body pt-3\\\"\u003e\\n \u003cdiv class=\\\"table-wrap\\\"\u003e\\n \u003ctable class=\\\"table is-striped is-hoverable is-fullwidth\\\"\u003e\\n \u003cthead\u003e\\n \u003ctr\u003e\\n \u003cth data-key=\\\"supplier_name\\\" data-type=\\\"str\\\"\u003e供应商名称\u003c/th\u003e\\n \u003cth data-key=\\\"category\\\" data-type=\\\"str\\\"\u003e品类\u003c/th\u003e\\n \u003cth data-key=\\\"region\\\" data-type=\\\"str\\\"\u003e区域\u003c/th\u003e\\n \u003cth data-key=\\\"years\\\" data-type=\\\"num\\\"\u003e合作年限\u003c/th\u003e\\n \u003cth data-key=\\\"purchase_amt\\\" data-type=\\\"num\\\"\u003e采购额(万)\u003c/th\u003e\\n \u003cth data-key=\\\"order_cnt\\\" data-type=\\\"num\\\"\u003e订单量\u003c/th\u003e\\n \u003cth data-key=\\\"otd_rate\\\" data-type=\\\"num\\\"\u003e准时交付\u003c/th\u003e\\n \u003cth data-key=\\\"quality_rate\\\" data-type=\\\"num\\\"\u003e质量合格\u003c/th\u003e\\n \u003cth data-key=\\\"response_hours\\\" data-type=\\\"num\\\"\u003e响应(h)\u003c/th\u003e\\n \u003cth data-key=\\\"score\\\" data-type=\\\"num\\\"\u003e综合评分\u003c/th\u003e\\n \u003cth data-key=\\\"risk_level\\\" data-type=\\\"str\\\"\u003e风险\u003c/th\u003e\\n \u003cth data-key=\\\"coop_status\\\" data-type=\\\"str\\\"\u003e合作状态\u003c/th\u003e\\n \u003cth data-key=\\\"action\\\" data-type=\\\"str\\\"\u003e建议动作\u003c/th\u003e\\n \u003cth data-key=\\\"value_index\\\" data-type=\\\"num\\\"\u003e价值指数\u003c/th\u003e\\n \u003cth data-key=\\\"eval_date\\\" data-type=\\\"str\\\"\u003e最近评估\u003c/th\u003e\\n \u003c/tr\u003e\\n \u003c/thead\u003e\\n \u003ctbody id=\\\"table-body\\\"\u003e\u003c/tbody\u003e\\n \u003c/table\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003cdiv class=\\\"empty-note\\\" id=\\\"empty-note\\\"\u003e\\n \u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"1.6\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003ccircle cx=\\\"11\\\" cy=\\\"11\\\" r=\\\"8\\\"/\u003e\u003cline x1=\\\"21\\\" y1=\\\"21\\\" x2=\\\"16.65\\\" y2=\\\"16.65\\\"/\u003e\u003c/svg\u003e\\n \u003cdiv\u003e当前筛选条件下暂无数据,请调整筛选条件后重试。\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\u003c/section\u003e\\n\\n\\n\u003cscript id=\\\"__dashboard_data_gzip__\\\" type=\\\"application/json\\\"\u003e\\\"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\\\"\u003c/script\u003e\\n\u003cscript\u003e\\nconst DASHBOARD_DATA = (async () =\u003e {\\n const dataEl = document.getElementById(\\\"__dashboard_data_gzip__\\\");\\n if (!dataEl) {\\n throw new Error(\\\"Embedded dashboard data tag not found: __dashboard_data_gzip__\\\");\\n }\\n if (typeof DecompressionStream !== \\\"function\\\") {\\n throw new Error(\\\"This dashboard requires browser gzip decompression support.\\\");\\n }\\n const encoded = JSON.parse(dataEl.textContent || '\\\"\\\"');\\n const compressedBytes = Uint8Array.from(atob(encoded), char =\u003e char.charCodeAt(0));\\n const decompressedStream = new Blob([compressedBytes]).stream().pipeThrough(new DecompressionStream(\\\"gzip\\\"));\\n const jsonText = await new Response(decompressedStream).text();\\n return JSON.parse(jsonText);\\n})();\\n\\n/* ================= 配色与常量 ================= */\\nconst PALETTE = ['#2F6FED','#12B981','#F5A524','#E5484D','#8B5CF6','#0EA5E9','#EC4899','#84CC16'];\\nconst RISK_COLOR = { '低':'#12B981', '中':'#F5A524', '高':'#E5484D' };\\nconst STATUS_COLOR = { '战略合作':'#8B5CF6', '重点合作':'#2F6FED', '一般合作':'#94A3B8', '观察中':'#E5484D' };\\nconst ACTION_COLOR = { '加大采购':'#12B981', '维持合作':'#2F6FED', '优化议价':'#F5A524', '加强监控':'#E5484D' };\\nconst RISK_ORDER = ['低','中','高'];\\nconst STATUS_ORDER = ['战略合作','重点合作','一般合作','观察中'];\\nconst ACTION_ORDER = ['加大采购','维持合作','优化议价','加强监控'];\\nconst TT = {\\n backgroundColor:'#0f2742', borderWidth:0, padding:[10,14],\\n textStyle:{ color:'#eaf1ff', fontSize:12 },\\n extraCssText:'box-shadow:0 10px 28px rgba(15,39,66,.28);border-radius:10px;'\\n};\\nconst AXIS = { color:'#66758c', fontSize:11 };\\nconst SPLIT = { lineStyle:{ color:'#edf1f9' } };\\n\\n/* ================= 状态 ================= */\\nconst state = { category:'全部', region:'全部', risk:'全部', status:'全部', action:'全部', search:'', sortKey:'value_index', sortDir:-1 };\\nlet rows = [];\\nconst charts = {};\\n\\n/* ================= 工具函数 ================= */\\nfunction fmt(n, d=0){\\n if(n === null || n === undefined || isNaN(n)) return '—';\\n return Number(n).toLocaleString('zh-CN', { minimumFractionDigits:d, maximumFractionDigits:d });\\n}\\nfunction pct(x, d=1){ return (x*100).toFixed(d) + '%'; }\\nfunction median(arr){\\n if(!arr.length) return 0;\\n const s = [...arr].sort((a,b)=\u003ea-b);\\n const m = Math.floor(s.length/2);\\n return s.length % 2 ? s[m] : (s[m-1]+s[m])/2;\\n}\\nfunction groupBy(arr, key){\\n const map = new Map();\\n arr.forEach(r =\u003e { const k = r[key]; map.set(k, (map.get(k)||[]).concat(r)); });\\n return map;\\n}\\nfunction filtered(){\\n return rows.filter(r =\u003e\\n (state.category==='全部' || r.category===state.category) \u0026\u0026\\n (state.region==='全部' || r.region===state.region) \u0026\u0026\\n (state.risk==='全部' || r.risk_level===state.risk) \u0026\u0026\\n (state.status==='全部' || r.coop_status===state.status) \u0026\u0026\\n (state.action==='全部' || r.action===state.action) \u0026\u0026\\n (!state.search ||\\n r.supplier_name.toLowerCase().includes(state.search) ||\\n r.supplier_id.toLowerCase().includes(state.search) ||\\n r.category.toLowerCase().includes(state.search))\\n );\\n}\\nfunction getChart(id){\\n if(!charts[id]) {\\n charts[id] = echarts.init(document.getElementById(id));\\n requestAnimationFrame(() =\u003e charts[id] \u0026\u0026 charts[id].resize());\\n }\\n return charts[id];\\n}\\nfunction emptyOption(text){\\n return {\\n graphic: [{ type:'text', left:'center', top:'middle', style:{ text: text || '暂无数据', fill:'#9aa8c0', fontSize:14, fontWeight:500 } }]\\n };\\n}\\n\\n/* ================= 筛选器初始化 ================= */\\nfunction populateFilters(){\\n const fill = (id, values) =\u003e {\\n const sel = document.getElementById(id);\\n values.forEach(v =\u003e {\\n const opt = document.createElement('option');\\n opt.value = v; opt.textContent = v;\\n sel.appendChild(opt);\\n });\\n };\\n fill('sel-category', [...new Set(rows.map(r=\u003er.category))].sort());\\n fill('sel-region', [...new Set(rows.map(r=\u003er.region))].sort());\\n fill('sel-risk', RISK_ORDER);\\n fill('sel-status', STATUS_ORDER);\\n fill('sel-action', ACTION_ORDER);\\n ['sel-category','sel-region','sel-risk','sel-status','sel-action'].forEach(id =\u003e {\\n document.getElementById(id).addEventListener('change', e =\u003e {\\n const keyMap = { 'sel-category':'category','sel-region':'region','sel-risk':'risk','sel-status':'status','sel-action':'action' };\\n state[keyMap[id]] = e.target.value;\\n renderAll();\\n });\\n });\\n document.getElementById('btn-reset').addEventListener('click', () =\u003e {\\n ['sel-category','sel-region','sel-risk','sel-status','sel-action'].forEach(id =\u003e { document.getElementById(id).value = '全部'; });\\n state.category='全部'; state.region='全部'; state.risk='全部'; state.status='全部'; state.action='全部';\\n state.search=''; document.getElementById('search-supplier').value='';\\n renderAll();\\n });\\n document.getElementById('search-supplier').addEventListener('input', e =\u003e {\\n state.search = e.target.value.trim().toLowerCase();\\n renderAll();\\n });\\n document.querySelectorAll('.table thead th').forEach(th =\u003e {\\n th.addEventListener('click', () =\u003e {\\n const key = th.dataset.key, type = th.dataset.type;\\n if(state.sortKey === key){ state.sortDir = -state.sortDir; } else { state.sortKey = key; state.sortDir = type==='str' ? 1 : -1; }\\n renderAll();\\n });\\n });\\n}\\n\\n/* ================= KPI ================= */\\nfunction renderKPIs(data){\\n const n = data.length;\\n const totalAmt = data.reduce((s,r)=\u003es+r.purchase_amt,0);\\n const avgValue = n ? data.reduce((s,r)=\u003es+r.value_index,0)/n : 0;\\n const avgScore = n ? data.reduce((s,r)=\u003es+r.score,0)/n : 0;\\n const avgOtd = n ? data.reduce((s,r)=\u003es+r.otd_rate,0)/n : 0;\\n const high = data.filter(r=\u003er.risk_level==='高').length;\\n const mid = data.filter(r=\u003er.risk_level==='中').length;\\n const low = data.filter(r=\u003er.risk_level==='低').length;\\n const maxValue = n ? Math.max(...data.map(r=\u003er.value_index)) : 0;\\n const maxScore = n ? Math.max(...data.map(r=\u003er.score)) : 0;\\n const cats = n ? new Set(data.map(r=\u003er.category)).size : 0;\\n const regs = n ? new Set(data.map(r=\u003er.region)).size : 0;\\n\\n document.getElementById('kpi-count').textContent = fmt(n);\\n document.getElementById('kpi-count-sub').textContent = `覆盖 ${cats} 个品类 / ${regs} 个区域`;\\n document.getElementById('kpi-amt').textContent = fmt(totalAmt,1);\\n document.getElementById('kpi-amt-sub').textContent = `单条均值 ${fmt(n?totalAmt/n:0,1)} 万`;\\n document.getElementById('kpi-value').textContent = fmt(avgValue,1);\\n document.getElementById('kpi-value-sub').textContent = `最高 ${fmt(maxValue,1)}`;\\n document.getElementById('kpi-score').textContent = fmt(avgScore,1);\\n document.getElementById('kpi-score-sub').textContent = `最高 ${fmt(maxScore,1)}`;\\n document.getElementById('kpi-otd').textContent = pct(avgOtd);\\n document.getElementById('kpi-otd-sub').textContent = n ? `最差 ${pct(Math.min(...data.map(r=\u003er.otd_rate)))}` : '—';\\n document.getElementById('kpi-risk').textContent = n ? pct(high/n,0) : '—';\\n document.getElementById('kpi-risk-sub').textContent = `高 ${high} · 中 ${mid} · 低 ${low}`;\\n}\\n\\n/* ================= 图表构建 ================= */\\nfunction baseGrid(extra){ return Object.assign({ left:12, right:20, top:56, bottom:10, containLabel:true }, extra||{}); }\\nfunction lg(x0,y0,x1,y1,c0,c1){ return new echarts.graphic.LinearGradient(0,0,1,0,[{offset:0,color:c0},{offset:1,color:c1}]); }\\n\\nfunction renderMatrix(data){\\n const chart = getChart('chart-matrix-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const xs = data.map(r=\u003er.purchase_amt), ys = data.map(r=\u003er.value_index);\\n const xMed = median(xs), yMed = median(ys);\\n const xMax = Math.max(...xs)*1.05, yMin = 70, yMax = 120;\\n const pts = data.map(r =\u003e ({\\n value:[r.purchase_amt, r.value_index, r.order_cnt],\\n risk:r.risk_level, name:r.supplier_name, category:r.category, region:r.region,\\n score:r.score, otd:r.otd_rate, quality:r.quality_rate, resp:r.response_hours, status:r.coop_status, action:r.action, years:r.years\\n }));\\n chart.setOption({\\n tooltip: Object.assign({}, TT, {\\n formatter(p){\\n const d = p.data;\\n return `\u003cb style=\\\"color:#fff\\\"\u003e${d.name}\u003c/b\u003e \u003cspan style=\\\"color:#8fb6ff\\\"\u003e(${d.category} · ${d.region})\u003c/span\u003e\u003cbr/\u003e`+\\n `年度采购额:${fmt(d.value[0],1)} 万元\u003cbr/\u003e订单量:${fmt(d.value[2])}\u003cbr/\u003e`+\\n `价值指数:\u003cb style=\\\"color:#4ade80\\\"\u003e${fmt(d.value[1],1)}\u003c/b\u003e | 综合评分:${fmt(d.score,1)}\u003cbr/\u003e`+\\n `准时交付:${pct(d.otd)} | 质量合格:${pct(d.quality)}\u003cbr/\u003e`+\\n `风险等级:\u003cb style=\\\"color:${RISK_COLOR[d.risk]}\\\"\u003e${d.risk}\u003c/b\u003e | 状态:${d.status} | 建议:${d.action}`;\\n }\\n }),\\n legend:{ data:RISK_ORDER, top:6, right:10, textStyle:{color:'#56647a',fontSize:12}, itemWidth:12, itemHeight:12, icon:'circle' },\\n grid: baseGrid({ left:14, right:30, top:26, bottom:8 }),\\n xAxis:{ type:'value', name:'年度采购额 (万元)', nameLocation:'middle', nameGap:32, nameTextStyle:{color:'#94a3b8',fontSize:12},\\n axisLabel:AXIS, splitLine:SPLIT },\\n yAxis:{ type:'value', name:'合作价值指数', nameLocation:'middle', nameGap:44, nameTextStyle:{color:'#94a3b8',fontSize:12},\\n min:70, max:120, interval:10, axisLabel:AXIS, splitLine:SPLIT },\\n series:[{\\n type:'scatter', data:pts, symbolSize:d =\u003e 9 + Math.sqrt(d[2])*0.85,\\n itemStyle:{ color:p =\u003e RISK_COLOR[p.data.risk], opacity:.8, borderColor:'#fff', borderWidth:1.2, shadowBlur:8, shadowColor:'rgba(18,35,61,.12)' },\\n emphasis:{ scale:1.35, itemStyle:{opacity:1} },\\n markArea:{\\n silent:true,\\n itemStyle:{ color:'rgba(47,111,237,0.05)' },\\n data:[\\n [{ coord:[xMed, yMax], label:{show:true, position:'insideTopLeft', color:'#1d55d0', fontWeight:800, fontSize:11, formatter:'核心伙伴\\\\n高价值 · 高采购'} }, { coord:[xMax, yMed] }],\\n [{ coord:[0, yMax], label:{show:true, position:'insideTopRight', color:'#0b8f63', fontWeight:800, fontSize:11, formatter:'潜力伙伴\\\\n高价值 · 低采购'} }, { coord:[xMed, yMed] }],\\n [{ coord:[xMed, yMin], label:{show:true, position:'insideBottomLeft', color:'#b26a05', fontWeight:800, fontSize:11, formatter:'议价谈判\\\\n低价值 · 高采购'} }, { coord:[xMax, yMin] }],\\n [{ coord:[0, yMin], label:{show:true, position:'insideBottomRight', color:'#94a3b8', fontWeight:800, fontSize:11, formatter:'观察优化\\\\n低价值 · 低采购'} }, { coord:[xMed, yMed] }]\\n ]\\n },\\n markLine:{\\n silent:true, symbol:'none',\\n lineStyle:{ type:'dashed', color:'#b6c4dc', width:1 },\\n label:{ show:false },\\n data:[ { xAxis:xMed }, { yAxis:yMed } ]\\n }\\n }]\\n }, true);\\n}\\n\\nfunction renderRiskStatus(data){\\n const riskChart = getChart('chart-risk-box');\\n const statusChart = getChart('chart-status-box');\\n if(!data.length){ riskChart.setOption(emptyOption(), true); statusChart.setOption(emptyOption(), true); return; }\\n const riskData = RISK_ORDER.map(k =\u003e ({ name:k, value:data.filter(r=\u003er.risk_level===k).length })).filter(d=\u003ed.value\u003e0);\\n const statusData = STATUS_ORDER.map(k =\u003e ({ name:k, value:data.filter(r=\u003er.coop_status===k).length })).filter(d=\u003ed.value\u003e0);\\n const donut = (dataArr, colors) =\u003e ({\\n tooltip: Object.assign({}, TT, { formatter:'{b}:{c} 家 ({d}%)' }),\\n legend:{ bottom:0, textStyle:{color:'#56647a',fontSize:11}, itemWidth:10, itemHeight:10, icon:'circle' },\\n series:[{\\n type:'pie', radius:['46%','68%'], center:['50%','42%'],\\n avoidLabelOverlap:true, label:{show:false}, emphasis:{label:{show:true, fontWeight:800, color:'#12233d', formatter:'{b}\\\\n{c} 家'}},\\n itemStyle:{ borderColor:'#fff', borderWidth:2 },\\n data:dataArr.map((d,i)=\u003e({ ...d, itemStyle:{ color:colors[i % colors.length] } }))\\n }]\\n });\\n riskChart.setOption(donut(riskData, RISK_ORDER.map(k=\u003eRISK_COLOR[k])), true);\\n statusChart.setOption(donut(statusData, STATUS_ORDER.map(k=\u003eSTATUS_COLOR[k])), true);\\n}\\n\\nfunction renderTop10(data){\\n const chart = getChart('chart-top10-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const top = [...data].sort((a,b)=\u003eb.value_index-a.value_index).slice(0,10).reverse();\\n chart.setOption({\\n tooltip: Object.assign({}, TT, {\\n trigger:'axis', axisPointer:{type:'shadow', shadowStyle:{color:'rgba(47,111,237,.06)'}},\\n formatter:ps =\u003e {\\n const d = top[ps[0].dataIndex];\\n return `\u003cb style=\\\"color:#fff\\\"\u003e${d.supplier_name}\u003c/b\u003e\u003cbr/\u003e价值指数:\u003cb style=\\\"color:#4ade80\\\"\u003e${fmt(d.value_index,1)}\u003c/b\u003e\u003cbr/\u003e采购额:${fmt(d.purchase_amt,1)} 万 | 评分:${fmt(d.score,1)}\u003cbr/\u003e风险:${d.risk_level} | 状态:${d.coop_status}`;\\n }\\n }),\\n grid: baseGrid({ left:8, right:52, top:16, bottom:6 }),\\n xAxis:{ type:'value', axisLabel:AXIS, splitLine:SPLIT },\\n yAxis:{ type:'category', inverse:true, data:top.map(r=\u003er.supplier_name),\\n axisLabel:{ color:'#33507a', fontSize:11, width:92, overflow:'truncate', fontWeight:600 } },\\n series:[{\\n type:'bar', data:top.map(r=\u003e({\\n value:r.value_index,\\n itemStyle:{ color:RISK_COLOR[r.risk_level], borderRadius:[0,6,6,0] }\\n })),\\n barWidth:15, showBackground:true, backgroundStyle:{ color:'#f1f5fd', borderRadius:[0,6,6,0] },\\n label:{ show:true, position:'right', formatter:p=\u003efmt(p.value,1), fontSize:11, color:'#33507a', fontWeight:700 }\\n }]\\n }, true);\\n}\\n\\nfunction renderCategory(data){\\n const chart = getChart('chart-category-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const g = groupBy(data, 'category');\\n const cats = [...g.keys()].sort((a,b)=\u003eg.get(b).reduce((s,r)=\u003es+r.purchase_amt,0) - g.get(a).reduce((s,r)=\u003es+r.purchase_amt,0));\\n const amts = cats.map(k =\u003e g.get(k).reduce((s,r)=\u003es+r.purchase_amt,0));\\n const avgs = cats.map(k =\u003e g.get(k).reduce((s,r)=\u003es+r.value_index,0)/g.get(k).length);\\n chart.setOption({\\n tooltip: Object.assign({}, TT, {\\n trigger:'axis', axisPointer:{type:'shadow', shadowStyle:{color:'rgba(47,111,237,.06)'}},\\n formatter:ps =\u003e {\\n const i = ps[0].dataIndex;\\n const list = g.get(cats[i]);\\n return `\u003cb style=\\\"color:#fff\\\"\u003e${cats[i]}\u003c/b\u003e\u003cbr/\u003e供应商:${list.length} 家\u003cbr/\u003e采购总额:\u003cb style=\\\"color:#7ab8ff\\\"\u003e${fmt(amts[i],1)}\u003c/b\u003e 万\u003cbr/\u003e平均价值指数:\u003cb style=\\\"color:#4ade80\\\"\u003e${fmt(avgs[i],1)}\u003c/b\u003e`;\\n }\\n }),\\n legend:{ data:['采购总额(万)','平均价值指数'], top:6, right:8, textStyle:{color:'#56647a',fontSize:11}, itemWidth:12, itemHeight:12, icon:'roundRect' },\\n grid: baseGrid({ left:6, right:8, top:48, bottom:4 }),\\n xAxis:{ type:'category', data:cats, axisLabel:{ color:'#33507a', fontSize:10, interval:0, rotate: cats.length\u003e5 ? 22 : 0 }, axisLine:{ lineStyle:{color:'#e3eaf5'} } },\\n yAxis:[\\n { type:'value', name:'采购额(万)', nameTextStyle:{color:'#94a3b8',fontSize:11}, axisLabel:AXIS, splitLine:SPLIT },\\n { type:'value', name:'指数', min:0, max:120, nameTextStyle:{color:'#94a3b8',fontSize:11}, axisLabel:AXIS, splitLine:{show:false} }\\n ],\\n series:[\\n { name:'采购总额(万)', type:'bar', data:amts, barWidth:18,\\n itemStyle:{ color:lg(0,0,0,1,'#2f6fed','#0ea5e9'), borderRadius:[5,5,0,0] },\\n label:{ show:true, position:'top', fontSize:10, color:'#66758c', formatter:p=\u003efmt(p.value,0) } },\\n { name:'平均价值指数', type:'line', yAxisIndex:1, data:avgs, smooth:true, symbolSize:7,\\n lineStyle:{ color:'#f5a524', width:2.5 }, itemStyle:{ color:'#f5a524', borderColor:'#fff', borderWidth:2 } }\\n ]\\n }, true);\\n}\\n\\nfunction renderRegion(data){\\n const chart = getChart('chart-region-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const g = groupBy(data, 'region');\\n const regions = [...g.keys()].sort((a,b)=\u003eg.get(b).reduce((s,r)=\u003es+r.purchase_amt,0) - g.get(a).reduce((s,r)=\u003es+r.purchase_amt,0));\\n const pieData = regions.map((k,i) =\u003e ({\\n name:k, value:g.get(k).reduce((s,r)=\u003es+r.purchase_amt,0),\\n itemStyle:{ color:PALETTE[i % PALETTE.length] }\\n }));\\n chart.setOption({\\n tooltip: Object.assign({}, TT, { formatter:p =\u003e `\u003cb style=\\\"color:#fff\\\"\u003e${p.name}\u003c/b\u003e\u003cbr/\u003e采购额:${fmt(p.value,1)} 万 (${p.percent}%)` }),\\n legend:{ bottom:0, type:'scroll', textStyle:{color:'#56647a',fontSize:11}, itemWidth:10, itemHeight:10, icon:'circle' },\\n series:[{\\n type:'pie', radius:['42%','66%'], center:['50%','42%'],\\n label:{ show:true, formatter:'{b}\\\\n{d}%', fontSize:10, color:'#56647a', fontWeight:600 },\\n labelLine:{ length:10, length2:8, lineStyle:{color:'#c6d2e8'} },\\n itemStyle:{ borderColor:'#fff', borderWidth:2 },\\n data:pieData\\n }]\\n }, true);\\n}\\n\\nfunction renderPerf(data){\\n const chart = getChart('chart-perf-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const xMean = median(data.map(r=\u003er.otd_rate)), yMean = median(data.map(r=\u003er.quality_rate));\\n const pts = data.map(r =\u003e ({\\n value:[r.otd_rate*100, r.quality_rate*100, r.purchase_amt],\\n risk:r.risk_level, name:r.supplier_name, category:r.category, score:r.score, vi:r.value_index\\n }));\\n chart.setOption({\\n tooltip: Object.assign({}, TT, {\\n formatter(p){\\n const d = p.data;\\n return `\u003cb style=\\\"color:#fff\\\"\u003e${d.name}\u003c/b\u003e (${d.category})\u003cbr/\u003e准时交付:\u003cb style=\\\"color:#7ab8ff\\\"\u003e${fmt(d.value[0],1)}%\u003c/b\u003e\u003cbr/\u003e质量合格:\u003cb style=\\\"color:#4ade80\\\"\u003e${fmt(d.value[1],1)}%\u003c/b\u003e\u003cbr/\u003e采购额:${fmt(d.value[2],1)} 万\u003cbr/\u003e价值指数:${fmt(d.vi,1)} | 风险:${d.risk}`;\\n }\\n }),\\n legend:{ data:RISK_ORDER, top:6, right:8, textStyle:{color:'#56647a',fontSize:11}, itemWidth:12, itemHeight:12, icon:'circle' },\\n grid: baseGrid({ left:6, right:10, top:48, bottom:4 }),\\n xAxis:{ type:'value', name:'准时交付率', nameLocation:'middle', nameGap:28, min:65, max:105, nameTextStyle:{color:'#94a3b8',fontSize:11},\\n axisLabel:{color:'#66758c',fontSize:10, formatter:'{value}%'}, splitLine:SPLIT },\\n yAxis:{ type:'value', name:'质量合格率', nameLocation:'middle', nameGap:34, min:70, max:105, nameTextStyle:{color:'#94a3b8',fontSize:11},\\n axisLabel:{color:'#66758c',fontSize:10, formatter:'{value}%'}, splitLine:SPLIT },\\n series:[{\\n type:'scatter', data:pts, symbolSize:d =\u003e 8 + Math.sqrt(d[2])*0.55,\\n itemStyle:{ color:p=\u003eRISK_COLOR[p.data.risk], opacity:.78, borderColor:'#fff', borderWidth:1.2, shadowBlur:6, shadowColor:'rgba(18,35,61,.1)' },\\n markLine:{\\n silent:true, symbol:'none', lineStyle:{ type:'dashed', color:'#b6c4dc' }, label:{ show:false },\\n data:[{ xAxis:xMean*100 }, { yAxis:yMean*100 }]\\n }\\n }]\\n }, true);\\n}\\n\\nfunction renderAction(data){\\n const chart = getChart('chart-action-box');\\n if(!data.length){ chart.setOption(emptyOption(), true); return; }\\n const counts = ACTION_ORDER.map(k =\u003e ({ name:k, value:data.filter(r=\u003er.action===k).length }));\\n chart.setOption({\\n tooltip: Object.assign({}, TT, { trigger:'axis', axisPointer:{type:'shadow', shadowStyle:{color:'rgba(47,111,237,.06)'}}, formatter:ps =\u003e `\u003cb style=\\\"color:#fff\\\"\u003e${ps[0].name}\u003c/b\u003e\u003cbr/\u003e供应商:${fmt(ps[0].value)} 家` }),\\n grid: baseGrid({ left:6, right:44, top:16, bottom:6 }),\\n xAxis:{ type:'value', minInterval:1, axisLabel:AXIS, splitLine:SPLIT },\\n yAxis:{ type:'category', inverse:true, data:counts.map(d=\u003ed.name), axisLabel:{ color:'#33507a', fontSize:12, fontWeight:700 } },\\n series:[{\\n type:'bar', data:counts.map(d =\u003e ({ value:d.value, itemStyle:{ color:ACTION_COLOR[d.name], borderRadius:[0,6,6,0] } })),\\n barWidth:20, showBackground:true, backgroundStyle:{ color:'#f1f5fd', borderRadius:[0,6,6,0] },\\n label:{ show:true, position:'right', formatter:p=\u003efmt(p.value), fontSize:12, color:'#33507a', fontWeight:800 }\\n }]\\n }, true);\\n}\\n\\n/* ================= 明细表 ================= */\\nfunction statusTag(s){\\n const map = { '战略合作':'t-violet', '重点合作':'t-blue', '一般合作':'t-gray', '观察中':'t-red' };\\n return `\u003cspan class=\\\"tag ${map[s]||'t-gray'}\\\"\u003e${s}\u003c/span\u003e`;\\n}\\nfunction riskTag(r){\\n const map = { '低':'t-green', '中':'t-amber', '高':'t-red' };\\n return `\u003cspan class=\\\"tag ${map[r]||'t-gray'}\\\"\u003e${r}\u003c/span\u003e`;\\n}\\nfunction actionTag(a){\\n const map = { '加大采购':'t-green', '维持合作':'t-blue', '优化议价':'t-amber', '加强监控':'t-red' };\\n return `\u003cspan class=\\\"tag ${map[a]||'t-gray'}\\\"\u003e${a}\u003c/span\u003e`;\\n}\\nfunction renderTable(data){\\n const sorted = [...data].sort((a,b) =\u003e {\\n const av = a[state.sortKey], bv = b[state.sortKey];\\n if(typeof av === 'number' \u0026\u0026 typeof bv === 'number') return (av-bv)*state.sortDir;\\n return String(av).localeCompare(String(bv), 'zh-CN')*state.sortDir;\\n });\\n document.getElementById('table-count-tag').textContent = `${data.length} 条`;\\n const body = document.getElementById('table-body');\\n if(!data.length){ body.innerHTML = `\u003ctr\u003e\u003ctd colspan=\\\"15\\\" style=\\\"text-align:center;color:#9aa8c0;padding:44px;\\\"\u003e无匹配数据\u003c/td\u003e\u003c/tr\u003e`; return; }\\n body.innerHTML = sorted.map(r =\u003e `\\n \u003ctr data-id=\\\"${r.supplier_id}\\\"\u003e\\n \u003ctd class=\\\"supplier-cell\\\"\u003e\u003cb\u003e${r.supplier_name}\u003c/b\u003e\u003cbr\u003e\u003cspan class=\\\"supplier-id\\\"\u003e${r.supplier_id}\u003c/span\u003e\u003c/td\u003e\\n \u003ctd\u003e${r.category}\u003c/td\u003e\\n \u003ctd\u003e${r.region}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${r.years} 年\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${fmt(r.purchase_amt,1)}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${fmt(r.order_cnt)}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${pct(r.otd_rate)}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${pct(r.quality_rate)}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${fmt(r.response_hours,1)}\u003c/td\u003e\\n \u003ctd class=\\\"num score-cell\\\"\u003e${fmt(r.score,1)}\u003c/td\u003e\\n \u003ctd\u003e${riskTag(r.risk_level)}\u003c/td\u003e\\n \u003ctd\u003e${statusTag(r.coop_status)}\u003c/td\u003e\\n \u003ctd\u003e${actionTag(r.action)}\u003c/td\u003e\\n \u003ctd class=\\\"num vi-cell\\\"\u003e${fmt(r.value_index,1)}\u003c/td\u003e\\n \u003ctd class=\\\"num\\\"\u003e${r.eval_date}\u003c/td\u003e\\n \u003c/tr\u003e`).join('');\\n}\\n\\n/* ================= 主渲染 ================= */\\nfunction renderAll(){\\n const data = filtered();\\n const isEmpty = data.length === 0;\\n document.getElementById('empty-note').style.display = isEmpty ? 'block' : 'none';\\n renderKPIs(data);\\n renderMatrix(data);\\n renderRiskStatus(data);\\n renderTop10(data);\\n renderCategory(data);\\n renderRegion(data);\\n renderPerf(data);\\n renderAction(data);\\n renderTable(data);\\n}\\n\\n/* ================= 启动 ================= */\\n(async function bootstrap(){\\n const dashboardData = await DASHBOARD_DATA;\\n rows = dashboardData.supplier_data || [];\\n const dates = rows.map(r=\u003er.eval_date).sort();\\n const meta = document.getElementById('header-meta');\\n meta.innerHTML = [\\n `\u003cspan class=\\\"head-chip\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003crect x=\\\"3\\\" y=\\\"4\\\" width=\\\"18\\\" height=\\\"18\\\" rx=\\\"2\\\" ry=\\\"2\\\"/\u003e\u003cline x1=\\\"16\\\" y1=\\\"2\\\" x2=\\\"16\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"8\\\" y1=\\\"2\\\" x2=\\\"8\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"10\\\" x2=\\\"21\\\" y2=\\\"10\\\"/\u003e\u003c/svg\u003e评估记录 \u003cb\u003e${rows.length}\u003c/b\u003e 条\u003c/span\u003e`,\\n `\u003cspan class=\\\"head-chip\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003crect x=\\\"3\\\" y=\\\"4\\\" width=\\\"18\\\" height=\\\"18\\\" rx=\\\"2\\\" ry=\\\"2\\\"/\u003e\u003cline x1=\\\"16\\\" y1=\\\"2\\\" x2=\\\"16\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"8\\\" y1=\\\"2\\\" x2=\\\"8\\\" y2=\\\"6\\\"/\u003e\u003cline x1=\\\"3\\\" y1=\\\"10\\\" x2=\\\"21\\\" y2=\\\"10\\\"/\u003e\u003c/svg\u003e数据范围 \u003cb\u003e${dates[0]}\u003c/b\u003e ~ \u003cb\u003e${dates[dates.length-1]}\u003c/b\u003e\u003c/span\u003e`,\\n `\u003cspan class=\\\"head-chip\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpolygon points=\\\"12 2 2 7 12 12 22 7 12 2\\\"/\u003e\u003cpolyline points=\\\"2 17 12 22 22 17\\\"/\u003e\u003cpolyline points=\\\"2 12 12 17 22 12\\\"/\u003e\u003c/svg\u003e覆盖 \u003cb\u003e${new Set(rows.map(r=\u003er.category)).size}\u003c/b\u003e 个品类\u003c/span\u003e`,\\n `\u003cspan class=\\\"head-chip\\\"\u003e\u003csvg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\u003e\u003cpath d=\\\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\\\"/\u003e\u003ccircle cx=\\\"12\\\" cy=\\\"10\\\" r=\\\"3\\\"/\u003e\u003c/svg\u003e覆盖 \u003cb\u003e${new Set(rows.map(r=\u003er.region)).size}\u003c/b\u003e 个区域\u003c/span\u003e`\\n ].join('');\\n populateFilters();\\n renderAll();\\n let t;\\n window.addEventListener('resize', () =\u003e {\\n clearTimeout(t);\\n t = setTimeout(() =\u003e Object.values(charts).forEach(c =\u003e c \u0026\u0026 c.resize()), 120);\\n });\\n})();\\n\u003c/script\u003e\\n\u003c/body\u003e\\n\u003c/html\u003e\\n\",\"dashboardHtmlPreview\":{\"title\":\"供应商合作价值评估看板\",\"metrics\":[\"供应商记录数\",\"年度采购总额 (万元)\",\"平均合作价值指数\",\"平均综合评分\",\"平均准时交付率\",\"高风险供应商占比\"]},\"html_content_version\":1}","shared":true,"updated_at":1788226636}