|
|
@@ -0,0 +1,585 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+<meta charset="UTF-8">
|
|
|
+<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
+<title>DAN 报告显示页面设计 · 8 类报告</title>
|
|
|
+<style>
|
|
|
+ :root{
|
|
|
+ --bg:#F3F2FA;
|
|
|
+ --card:#FFFFFF;
|
|
|
+ --violet:#6B5BD2;
|
|
|
+ --violet-deep:#4C3F91;
|
|
|
+ --violet-mid:#7A6ADB;
|
|
|
+ --violet-soft:#A99CF0;
|
|
|
+ --violet-text:#5B4BA8;
|
|
|
+ --violet-grid:#EDE8FB;
|
|
|
+ --violet-wash:#F7F5FE;
|
|
|
+ --ink:#33334A;
|
|
|
+ --ink-2:#6E6E85;
|
|
|
+ --ink-3:#9A9AB0;
|
|
|
+ --line:#EFEDF8;
|
|
|
+ --orange:#F0A05A;
|
|
|
+ --orange-wash:#FDF3E7;
|
|
|
+ --cyan:#67E8F9;
|
|
|
+ --green:#5FC08A;
|
|
|
+ --red:#E8776B;
|
|
|
+ --radius:16px;
|
|
|
+ }
|
|
|
+ *{box-sizing:border-box;margin:0;padding:0}
|
|
|
+ html,body{height:100%}
|
|
|
+ body{
|
|
|
+ font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",sans-serif;
|
|
|
+ background:#E7E4F3;color:var(--ink);-webkit-font-smoothing:antialiased;
|
|
|
+ }
|
|
|
+ .app{display:flex;min-height:100vh}
|
|
|
+
|
|
|
+ /* ============ 侧边栏 ============ */
|
|
|
+ .sidebar{
|
|
|
+ width:272px;flex:0 0 272px;background:#fff;padding:26px 20px;
|
|
|
+ border-right:1px solid #E4E0F0;position:sticky;top:0;height:100vh;overflow-y:auto;
|
|
|
+ }
|
|
|
+ .sidebar h1{font-size:19px;font-weight:700;color:var(--violet-deep);letter-spacing:.5px}
|
|
|
+ .sidebar .sub{font-size:12px;color:var(--ink-3);margin-top:5px;line-height:1.6}
|
|
|
+ .sidebar .meta{
|
|
|
+ margin-top:14px;padding:10px 12px;background:var(--violet-wash);
|
|
|
+ border-radius:10px;font-size:11.5px;color:var(--violet-text);line-height:1.7
|
|
|
+ }
|
|
|
+ .sidebar .meta b{color:var(--violet-deep)}
|
|
|
+ nav{margin-top:20px;display:flex;flex-direction:column;gap:6px}
|
|
|
+ .tab{
|
|
|
+ display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:11px;
|
|
|
+ cursor:pointer;border:1px solid transparent;transition:.16s;background:transparent;text-align:left;
|
|
|
+ font-family:inherit;width:100%;
|
|
|
+ }
|
|
|
+ .tab:hover{background:var(--violet-wash)}
|
|
|
+ .tab.active{background:linear-gradient(100deg,#F0EDFD,#F7F5FE);border-color:#DDD5F7}
|
|
|
+ .tab-code{
|
|
|
+ flex:0 0 30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
|
|
|
+ font-size:11.5px;font-weight:700;background:var(--violet-grid);color:var(--violet-text)
|
|
|
+ }
|
|
|
+ .tab.active .tab-code{background:var(--violet);color:#fff}
|
|
|
+ .tab-name{font-size:13.5px;font-weight:600;color:var(--ink)}
|
|
|
+ .tab-desc{font-size:11px;color:var(--ink-3);margin-top:1px}
|
|
|
+ .legend{margin-top:22px;padding-top:16px;border-top:1px solid var(--line)}
|
|
|
+ .legend h3{font-size:12px;color:var(--ink-2);margin-bottom:10px;font-weight:600}
|
|
|
+ .lg-row{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--ink-2);margin-bottom:7px}
|
|
|
+ .lg-dot{width:11px;height:11px;border-radius:3px;flex:0 0 11px}
|
|
|
+
|
|
|
+ /* ============ 舞台 ============ */
|
|
|
+ .stage{flex:1;display:flex;flex-direction:column;align-items:center;padding:30px 24px 50px;overflow-y:auto;height:100vh}
|
|
|
+ .stage-head{text-align:center;margin-bottom:18px}
|
|
|
+ .stage-head .t{font-size:15px;font-weight:600;color:var(--violet-deep)}
|
|
|
+ .stage-head .d{font-size:12px;color:var(--ink-3);margin-top:4px}
|
|
|
+ .phone{
|
|
|
+ width:392px;background:var(--bg);border-radius:30px;overflow:hidden;
|
|
|
+ box-shadow:0 18px 48px rgba(60,45,120,.20),0 2px 8px rgba(60,45,120,.10);
|
|
|
+ border:7px solid #2E2A44;
|
|
|
+ }
|
|
|
+ .screen{min-height:640px;padding-bottom:18px}
|
|
|
+
|
|
|
+ /* ============ Hero ============ */
|
|
|
+ .hero{
|
|
|
+ position:relative;overflow:hidden;color:#fff;padding:22px 20px 20px;
|
|
|
+ background:linear-gradient(160deg,#4C3F91 0%,#6B5BD2 55%,#8B7BE8 100%);
|
|
|
+ border-bottom-left-radius:22px;border-bottom-right-radius:22px;
|
|
|
+ }
|
|
|
+ .hero-c1{position:absolute;width:190px;height:190px;border-radius:50%;background:rgba(255,255,255,.06);right:-70px;top:-78px}
|
|
|
+ .hero-c2{position:absolute;width:112px;height:112px;border-radius:50%;background:rgba(255,255,255,.05);left:-42px;bottom:-34px}
|
|
|
+ .hero-top{position:relative;z-index:1}
|
|
|
+ .hero-name{font-size:21px;font-weight:700;letter-spacing:.3px}
|
|
|
+ .hero-badges{display:flex;align-items:center;gap:6px;margin-top:8px;flex-wrap:wrap}
|
|
|
+ .bd{font-size:10.5px;padding:3px 9px;border-radius:20px;background:rgba(255,255,255,.20);backdrop-filter:blur(2px)}
|
|
|
+ .bd-strong{background:#FFD9A8;color:#7A4A12;font-weight:700}
|
|
|
+ .hero-scores{display:flex;align-items:flex-end;gap:26px;margin-top:16px;position:relative;z-index:1}
|
|
|
+ .hs{display:flex;flex-direction:column;gap:2px}
|
|
|
+ .hs-num{font-size:32px;font-weight:800;line-height:1;letter-spacing:-.5px}
|
|
|
+ .hs-num small{font-size:13px;font-weight:600;opacity:.8;margin-left:2px}
|
|
|
+ .hs-lab{font-size:10.5px;opacity:.82}
|
|
|
+ .pct-wrap{margin-top:14px;position:relative;z-index:1}
|
|
|
+ .pct-track{height:7px;border-radius:4px;background:rgba(255,255,255,.24);position:relative;overflow:hidden}
|
|
|
+ .pct-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,#A5F3FC,#67E8F9,#FFD9A8)}
|
|
|
+ .pct-txt{margin-top:6px;font-size:10.5px;opacity:.9}
|
|
|
+
|
|
|
+ /* ============ 卡片 ============ */
|
|
|
+ .card{background:var(--card);border-radius:var(--radius);margin:11px 12px 0;padding:15px 15px 16px;box-shadow:0 1px 3px rgba(80,60,140,.05)}
|
|
|
+ .card-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:2px}
|
|
|
+ .card-title{font-size:14.5px;font-weight:700;color:var(--violet-text)}
|
|
|
+ .card-note{font-size:10.5px;color:var(--ink-3)}
|
|
|
+ .card-sub{font-size:11px;color:var(--ink-3);margin-top:3px;line-height:1.6}
|
|
|
+
|
|
|
+ /* 雷达 + 指标条 */
|
|
|
+ .radar-box{display:flex;justify-content:center;margin:6px 0 2px}
|
|
|
+ .m-list{margin-top:10px}
|
|
|
+ .metric{display:flex;align-items:center;gap:9px;padding:6px 0}
|
|
|
+ .metric-lab{flex:0 0 88px;font-size:11.5px;color:var(--ink-2);line-height:1.3}
|
|
|
+ .metric-track{flex:1;height:8px;border-radius:4px;background:var(--violet-grid);position:relative;overflow:hidden}
|
|
|
+ .metric-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,var(--violet-soft),var(--violet))}
|
|
|
+ .metric-fill.warn{background:linear-gradient(90deg,#F7C08A,var(--orange))}
|
|
|
+ .metric-fill.good{background:linear-gradient(90deg,#8FD9B0,var(--green))}
|
|
|
+ .metric-ref{position:absolute;top:-2px;width:1.5px;height:12px;background:#B9B4D4;border-radius:1px}
|
|
|
+ .metric-val{flex:0 0 46px;text-align:right;font-size:11.5px;font-weight:700;color:var(--ink)}
|
|
|
+ .metric-val.warn{color:var(--orange)}
|
|
|
+ .tag-mini{font-size:9px;padding:1px 5px;border-radius:4px;background:var(--orange-wash);color:#B4702A;margin-left:4px;font-weight:600}
|
|
|
+ .tag-mini.good{background:#E9F7EF;color:#2E8B5C}
|
|
|
+ .metric-val .tag-mini{display:inline-block}
|
|
|
+
|
|
|
+ /* chips */
|
|
|
+ .chip-row{display:flex;align-items:center;gap:9px;padding:6px 0}
|
|
|
+ .chip-lab{flex:0 0 60px;font-size:11.5px;color:var(--violet-text);font-weight:600}
|
|
|
+ .chip-track{flex:1;height:7px;border-radius:4px;background:var(--violet-grid);overflow:hidden}
|
|
|
+ .chip-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,#B9AEF5,var(--violet))}
|
|
|
+ .chip-fill.warn{background:linear-gradient(90deg,#F7C08A,var(--orange))}
|
|
|
+ .chip-val{flex:0 0 40px;text-align:right;font-size:11px;color:var(--ink-2)}
|
|
|
+
|
|
|
+ /* grid */
|
|
|
+ .grid{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
|
|
|
+ .gi{flex:0 0 calc(33.333% - 6px);background:var(--violet-wash);border-radius:11px;padding:11px 6px;text-align:center}
|
|
|
+ .gi-v{font-size:16px;font-weight:800;color:var(--violet-deep);line-height:1}
|
|
|
+ .gi-v small{font-size:10px;font-weight:600;color:var(--ink-3);margin-left:1px}
|
|
|
+ .gi-l{font-size:10px;color:var(--ink-3);margin-top:5px}
|
|
|
+ .habit{margin-top:10px;border-top:1px solid var(--line);padding-top:9px}
|
|
|
+ .habit-row{display:flex;justify-content:space-between;font-size:11.5px;color:var(--ink-2);padding:4px 0}
|
|
|
+ .habit-row b{color:var(--ink);font-weight:600}
|
|
|
+
|
|
|
+ /* matrix(社会关系依恋) */
|
|
|
+ .mx-head,.mx-row{display:flex;align-items:center;padding:7px 0;font-size:11.5px}
|
|
|
+ .mx-head{border-bottom:1px solid var(--line);color:var(--ink-3);font-size:10.5px;font-weight:600}
|
|
|
+ .mx-c0{flex:0 0 52px;color:var(--ink-2)}
|
|
|
+ .mx-c{flex:1;text-align:center}
|
|
|
+ .mx-bar{height:6px;border-radius:3px;background:var(--violet-grid);overflow:hidden;margin:0 8px}
|
|
|
+ .mx-bar i{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,var(--violet-soft),var(--violet))}
|
|
|
+ .mx-num{font-weight:700;color:var(--violet-text)}
|
|
|
+
|
|
|
+ /* duration(时长卡) */
|
|
|
+ .dur{display:flex;gap:8px;margin-top:10px}
|
|
|
+ .du{flex:1;background:var(--violet-wash);border-radius:12px;padding:11px 9px;text-align:center}
|
|
|
+ .du-v{font-size:18px;font-weight:800;color:var(--violet-deep);line-height:1}
|
|
|
+ .du-v small{font-size:10px;color:var(--ink-3);font-weight:600;margin-left:1px}
|
|
|
+ .du-l{font-size:10px;color:var(--ink-3);margin-top:5px}
|
|
|
+ .du-s{font-size:9.5px;margin-top:6px;padding:2px 6px;border-radius:5px;display:inline-block;font-weight:600}
|
|
|
+ .du-s.ok{background:#E9F7EF;color:#2E8B5C}
|
|
|
+ .du-s.warn{background:var(--orange-wash);color:#B4702A}
|
|
|
+ .du-s.bad{background:#FDECEA;color:#C25A4E}
|
|
|
+
|
|
|
+ /* compass */
|
|
|
+ .compass-note{font-size:11px;color:var(--ink-2);line-height:1.7;margin-top:8px}
|
|
|
+
|
|
|
+ /* text */
|
|
|
+ .txt{font-size:12px;color:var(--ink-2);line-height:1.85;margin-top:8px}
|
|
|
+ .txt.collapsed{
|
|
|
+ display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;
|
|
|
+ -webkit-mask-image:linear-gradient(180deg,#000 55%,transparent 100%);
|
|
|
+ }
|
|
|
+ .more{font-size:11.5px;color:var(--violet);margin-top:6px;font-weight:600;cursor:pointer;background:none;border:none;padding:0;font-family:inherit}
|
|
|
+
|
|
|
+ /* 优势/待提升 */
|
|
|
+ .two{display:flex;gap:8px;margin-top:10px}
|
|
|
+ .two-col{flex:1;background:var(--violet-wash);border-radius:12px;padding:11px}
|
|
|
+ .two-col.warn{background:var(--orange-wash)}
|
|
|
+ .two-h{font-size:11px;font-weight:700;margin-bottom:7px}
|
|
|
+ .two-col .two-h{color:#2E8B5C}
|
|
|
+ .two-col.warn .two-h{color:#B4702A}
|
|
|
+ .two-item{font-size:11px;color:var(--ink-2);padding:2.5px 0}
|
|
|
+
|
|
|
+ /* 推荐 chips */
|
|
|
+ .rec{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
|
|
|
+ .rec-chip{font-size:11px;padding:5px 10px;border-radius:20px;background:var(--violet-wash);color:var(--violet-text);font-weight:600}
|
|
|
+ .rec-chip.hot{background:linear-gradient(100deg,#F0EDFD,#E7E1FB);color:var(--violet-deep)}
|
|
|
+
|
|
|
+ .foot{text-align:center;font-size:10px;color:#B0AEC4;padding:18px 26px 4px;line-height:1.7}
|
|
|
+ .hint{font-size:11px;color:var(--ink-3);margin-top:14px;text-align:center}
|
|
|
+</style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+<div class="app">
|
|
|
+ <aside class="sidebar">
|
|
|
+ <h1>DAN 报告体系</h1>
|
|
|
+ <div class="sub">8 类报告 · 显示页面设计原型</div>
|
|
|
+ <div class="meta">
|
|
|
+ 数据来源 <b>DanReportUpload.DIM_*</b><br>
|
|
|
+ 区块顺序 <b>ReportBlockAssembler<br>.DAN_CATEGORY_TITLES</b><br>
|
|
|
+ 渲染口径 <b>score / indicator / text</b>
|
|
|
+ </div>
|
|
|
+ <nav id="tabs"></nav>
|
|
|
+ <div class="legend">
|
|
|
+ <h3>区块渲染器图例</h3>
|
|
|
+ <div class="lg-row"><span class="lg-dot" style="background:var(--violet)"></span>雷达图(≥3 维)</div>
|
|
|
+ <div class="lg-row"><span class="lg-dot" style="background:var(--violet-soft)"></span>指标条(带参考线)</div>
|
|
|
+ <div class="lg-row"><span class="lg-dot" style="background:var(--orange)"></span>需关注(低于阈值)</div>
|
|
|
+ <div class="lg-row"><span class="lg-dot" style="background:var(--green)"></span>优势项</div>
|
|
|
+ <div class="lg-row"><span class="lg-dot" style="background:#D7D2EC"></span>数值格 / 时长卡</div>
|
|
|
+ </div>
|
|
|
+ </aside>
|
|
|
+
|
|
|
+ <main class="stage">
|
|
|
+ <div class="stage-head">
|
|
|
+ <div class="t" id="stageTitle"></div>
|
|
|
+ <div class="d" id="stageDesc"></div>
|
|
|
+ </div>
|
|
|
+ <div class="phone"><div class="screen" id="screen"></div></div>
|
|
|
+ <div class="hint">切换左侧报告类别查看各自专属页面布局</div>
|
|
|
+ </main>
|
|
|
+</div>
|
|
|
+
|
|
|
+<script>
|
|
|
+/* ===================== 雷达图(SVG) ===================== */
|
|
|
+function radarSVG(items, opt){
|
|
|
+ opt = opt || {};
|
|
|
+ var size=250, cx=125, cy=121, r=82, n=items.length, rings='', axes='', i, a, pts;
|
|
|
+ for(var g=1; g<=4; g++){
|
|
|
+ pts=[];
|
|
|
+ for(i=0;i<n;i++){ a=-Math.PI/2+i*2*Math.PI/n; pts.push((cx+r*g/4*Math.cos(a)).toFixed(1)+','+(cy+r*g/4*Math.sin(a)).toFixed(1)); }
|
|
|
+ rings+='<polygon points="'+pts.join(' ')+'" fill="'+(g===4?'#F7F5FE':'none')+'" stroke="#E6E1F7" stroke-width="1"/>';
|
|
|
+ }
|
|
|
+ for(i=0;i<n;i++){
|
|
|
+ a=-Math.PI/2+i*2*Math.PI/n;
|
|
|
+ axes+='<line x1="'+cx+'" y1="'+cy+'" x2="'+(cx+r*Math.cos(a)).toFixed(1)+'" y2="'+(cy+r*Math.sin(a)).toFixed(1)+'" stroke="#E6E1F7" stroke-width="1"/>';
|
|
|
+ }
|
|
|
+ var dpts=items.map(function(it,i){
|
|
|
+ var a=-Math.PI/2+i*2*Math.PI/n, ratio=Math.max(0,Math.min(1,it.value/it.max));
|
|
|
+ return (cx+r*ratio*Math.cos(a)).toFixed(1)+','+(cy+r*ratio*Math.sin(a)).toFixed(1);
|
|
|
+ });
|
|
|
+ var data='<polygon points="'+dpts.join(' ')+'" fill="rgba(107,91,210,.20)" stroke="#6B5BD2" stroke-width="2" stroke-linejoin="round"/>';
|
|
|
+ var dots=items.map(function(it,i){
|
|
|
+ var a=-Math.PI/2+i*2*Math.PI/n, ratio=Math.max(0,Math.min(1,it.value/it.max));
|
|
|
+ var warn = it.max && it.value/it.max < 0.5;
|
|
|
+ return '<circle cx="'+(cx+r*ratio*Math.cos(a)).toFixed(1)+'" cy="'+(cy+r*ratio*Math.sin(a)).toFixed(1)+'" r="3" fill="'+(warn?'#F0A05A':'#6B5BD2')+'"/>';
|
|
|
+ }).join('');
|
|
|
+ var labels=items.map(function(it,i){
|
|
|
+ var a=-Math.PI/2+i*2*Math.PI/n, lx=cx+(r+24)*Math.cos(a), ly=cy+(r+24)*Math.sin(a);
|
|
|
+ var cos=Math.cos(a), anchor = Math.abs(cos)<0.25 ? 'middle' : (cos>0?'start':'end');
|
|
|
+ var dy = Math.sin(a)>0.6 ? 8 : (Math.sin(a)<-0.6 ? -2 : 4);
|
|
|
+ return '<text x="'+lx.toFixed(1)+'" y="'+(ly+dy).toFixed(1)+'" text-anchor="'+anchor+'" font-size="10.5" fill="#6E6E85">'+it.label+'</text>';
|
|
|
+ }).join('');
|
|
|
+ return '<svg viewBox="0 0 '+size+' '+size+'" width="100%" style="max-width:250px;display:block">'+rings+axes+data+dots+labels+'</svg>';
|
|
|
+}
|
|
|
+
|
|
|
+/* ===================== 区块渲染器 ===================== */
|
|
|
+function pct(v,m){ return Math.round(Math.max(0,Math.min(1,v/m))*100); }
|
|
|
+
|
|
|
+function rBars(b){
|
|
|
+ var h='<div class="m-list">';
|
|
|
+ b.items.forEach(function(it){
|
|
|
+ var w=pct(it.value,it.max), warn = it.value/it.max < 0.5, good = it.value/it.max >= 0.8;
|
|
|
+ h+='<div class="metric">'
|
|
|
+ +'<div class="metric-lab">'+it.label+'</div>'
|
|
|
+ +'<div class="metric-track"><div class="metric-fill '+(warn?'warn':(good?'good':''))+'" style="width:'+w+'%"></div>'
|
|
|
+ +(it.ref?'<div class="metric-ref" style="left:'+pct(it.ref,it.max)+'%"></div>':'')+'</div>'
|
|
|
+ +'<div class="metric-val'+(warn?' warn':'')+'">'+it.value
|
|
|
+ +(b.maxLabel?'<span style="font-weight:500;color:#9A9AB0;font-size:10px">/'+it.max+'</span>':'')
|
|
|
+ +(warn?'<span class="tag-mini">需关注</span>':'')+'</div>'
|
|
|
+ +'</div>';
|
|
|
+ });
|
|
|
+ return h+'</div>';
|
|
|
+}
|
|
|
+function rRadar(b){
|
|
|
+ return '<div class="radar-box">'+radarSVG(b.items)+'</div>'+rBars(b);
|
|
|
+}
|
|
|
+function rChips(b){
|
|
|
+ var h='<div class="m-list">';
|
|
|
+ b.items.forEach(function(it){
|
|
|
+ var w=pct(it.value,it.max), warn=it.value/it.max>=0.5;
|
|
|
+ h+='<div class="chip-row"><div class="chip-lab">'+it.label+'</div>'
|
|
|
+ +'<div class="chip-track"><div class="chip-fill '+(warn?'warn':'')+'" style="width:'+w+'%"></div></div>'
|
|
|
+ +'<div class="chip-val">'+it.value+'/'+it.max+'</div></div>';
|
|
|
+ });
|
|
|
+ return h+'</div>';
|
|
|
+}
|
|
|
+function rGrid(b){
|
|
|
+ var h='<div class="grid">';
|
|
|
+ b.items.forEach(function(it){
|
|
|
+ h+='<div class="gi"><div class="gi-v">'+it.value+'<small>'+(it.unit||'')+'</small></div><div class="gi-l">'+it.label+'</div></div>';
|
|
|
+ });
|
|
|
+ h+='</div>';
|
|
|
+ if(b.habits){
|
|
|
+ h+='<div class="habit">';
|
|
|
+ b.habits.forEach(function(x){ h+='<div class="habit-row"><span>'+x.k+'</span><b>'+x.v+'</b></div>'; });
|
|
|
+ h+='</div>';
|
|
|
+ }
|
|
|
+ return h;
|
|
|
+}
|
|
|
+function rMatrix(b){
|
|
|
+ var h='<div class="mx-head"><div class="mx-c0"></div>';
|
|
|
+ b.cols.forEach(function(c){ h+='<div class="mx-c">'+c+'</div>'; });
|
|
|
+ h+='</div>';
|
|
|
+ b.rows.forEach(function(r){
|
|
|
+ h+='<div class="mx-row"><div class="mx-c0">'+r.label+'</div>';
|
|
|
+ r.vals.forEach(function(v){
|
|
|
+ h+='<div class="mx-c"><div class="mx-bar"><i style="width:'+v+'%"></i></div><div class="mx-num" style="font-size:10.5px;margin-top:3px">'+v+'</div></div>';
|
|
|
+ });
|
|
|
+ h+='</div>';
|
|
|
+ });
|
|
|
+ return h;
|
|
|
+}
|
|
|
+function rDuration(b){
|
|
|
+ var h='<div class="dur">';
|
|
|
+ b.items.forEach(function(it){
|
|
|
+ h+='<div class="du"><div class="du-v">'+it.value+'<small>'+it.unit+'</small></div>'
|
|
|
+ +'<div class="du-l">'+it.label+'</div>'
|
|
|
+ +'<div class="du-s '+it.status+'">'+it.note+'</div></div>';
|
|
|
+ });
|
|
|
+ return h+'</div>';
|
|
|
+}
|
|
|
+function rCompass(b){
|
|
|
+ var svg='<svg viewBox="0 0 220 190" width="100%" style="max-width:240px;display:block;margin:4px auto 0">'
|
|
|
+ +'<circle cx="110" cy="95" r="78" fill="#F7F5FE" stroke="#E6E1F7"/>'
|
|
|
+ +'<circle cx="110" cy="95" r="52" fill="none" stroke="#EDE8FB"/>'
|
|
|
+ +'<circle cx="110" cy="95" r="26" fill="none" stroke="#EDE8FB"/>'
|
|
|
+ +'<line x1="32" y1="95" x2="188" y2="95" stroke="#E6E1F7"/>'
|
|
|
+ +'<line x1="110" y1="17" x2="110" y2="173" stroke="#E6E1F7"/>';
|
|
|
+ var pos=[{x:110,y:35},{x:110,y:155},{x:47,y:95},{x:173,y:95}];
|
|
|
+ b.items.forEach(function(it,i){
|
|
|
+ var p=pos[i], rr=(1-it.value/it.max)*72;
|
|
|
+ var ang=Math.atan2(p.y-95,p.x-110);
|
|
|
+ var dx=110+rr*Math.cos(ang), dy=95+rr*Math.sin(ang);
|
|
|
+ svg+='<line x1="110" y1="95" x2="'+dx.toFixed(1)+'" y2="'+dy.toFixed(1)+'" stroke="#C9C1EE" stroke-dasharray="3 3"/>';
|
|
|
+ svg+='<circle cx="'+dx.toFixed(1)+'" cy="'+dy.toFixed(1)+'" r="'+(6+it.value/it.max*9).toFixed(1)+'" fill="rgba(107,91,210,.28)" stroke="#6B5BD2" stroke-width="1.6"/>';
|
|
|
+ var lx = p.x===110 ? 110 : (p.x<110? 40 : 180), ly = p.y<95 ? 22 : 172;
|
|
|
+ var anchor = p.x===110 ? 'middle' : (p.x<110?'start':'end');
|
|
|
+ svg+='<text x="'+lx+'" y="'+ly+'" text-anchor="'+anchor+'" font-size="11" fill="#5B4BA8" font-weight="600">'+it.label+'</text>';
|
|
|
+ svg+='<text x="'+lx+'" y="'+(ly+13)+'" text-anchor="'+anchor+'" font-size="9.5" fill="#9A9AB0">'+it.value+'/'+it.max+'</text>';
|
|
|
+ });
|
|
|
+ svg+='</svg>';
|
|
|
+ return svg+'<div class="compass-note">'+b.note+'</div>';
|
|
|
+}
|
|
|
+function rText(b){
|
|
|
+ var cls = b.collapsible ? 'txt collapsed' : 'txt';
|
|
|
+ var h='<div class="'+cls+'" id="'+b._id+'">'+b.content+'</div>';
|
|
|
+ if(b.collapsible) h+='<button class="more" data-t="'+b._id+'">展开全文 ›</button>';
|
|
|
+ return h;
|
|
|
+}
|
|
|
+function rTwo(b){
|
|
|
+ var h='<div class="two">';
|
|
|
+ h+='<div class="two-col"><div class="two-h">优势维度</div>';
|
|
|
+ b.good.forEach(function(x){ h+='<div class="two-item">· '+x+'</div>'; });
|
|
|
+ h+='</div><div class="two-col warn"><div class="two-h">待提升</div>';
|
|
|
+ b.warn.forEach(function(x){ h+='<div class="two-item">· '+x+'</div>'; });
|
|
|
+ h+='</div></div>';
|
|
|
+ return h;
|
|
|
+}
|
|
|
+function rRec(b){
|
|
|
+ var h='<div class="rec">';
|
|
|
+ b.items.forEach(function(it){ h+='<span class="rec-chip'+(it.hot?' hot':'')+'">'+it.label+'</span>'; });
|
|
|
+ return h+'</div>';
|
|
|
+}
|
|
|
+
|
|
|
+var RENDER={radar:rRadar,bars:rBars,chips:rChips,grid:rGrid,matrix:rMatrix,duration:rDuration,compass:rCompass,text:rText,two:rTwo,rec:rRec};
|
|
|
+
|
|
|
+/* ===================== 8 类报告数据 ===================== */
|
|
|
+var MEMBER={name:'陈乐乐',gender:'女',age:'9岁'};
|
|
|
+var REPORTS=[
|
|
|
+{
|
|
|
+ id:'mind',code:'A2',name:'心维度',desc:'核心素养评估 · mind',
|
|
|
+ total:78,percentile:72,level:'B',date:'2026-10-18',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'认知能力',note:'百分位',maxLabel:true,items:[
|
|
|
+ {label:'感知觉',value:82,max:100},{label:'记忆力',value:74,max:100},{label:'注意力',value:68,max:100}]},
|
|
|
+ {type:'radar',title:'大五人格',note:'1-5 分制',maxLabel:true,items:[
|
|
|
+ {label:'开放性',value:4.2,max:5},{label:'尽责性',value:3.8,max:5},{label:'外向性',value:3.1,max:5},
|
|
|
+ {label:'宜人性',value:4.5,max:5},{label:'神经质',value:2.4,max:5}]},
|
|
|
+ {type:'chips',title:'情绪状态',note:'0-15 分制,分数越高越需关注',items:[
|
|
|
+ {label:'自卑感',value:4,max:15},{label:'抑郁',value:3,max:15},{label:'焦虑',value:6,max:15},{label:'无力感',value:3,max:15}]},
|
|
|
+ {type:'matrix',title:'社会关系',note:'依恋质量 · 母亲 / 父亲 / 同伴',
|
|
|
+ cols:['信任','沟通','亲近'],
|
|
|
+ rows:[
|
|
|
+ {label:'母亲',vals:[86,78,82]},
|
|
|
+ {label:'父亲',vals:[71,64,69]},
|
|
|
+ {label:'同伴',vals:[74,80,77]}]},
|
|
|
+ {type:'grid',title:'体质健康',items:[
|
|
|
+ {label:'身高',value:132,unit:'cm'},{label:'体重',value:28,unit:'kg'},{label:'BMI',value:16.1,unit:''}],
|
|
|
+ habits:[{k:'饮食',v:'规律'},{k:'睡眠',v:'约 9 小时/天'},{k:'运动',v:'每周 3 次'}]},
|
|
|
+ {type:'bars',title:'综合能力',maxLabel:true,items:[
|
|
|
+ {label:'语言表达',value:8.1,max:10},{label:'逻辑思维',value:7.4,max:10},{label:'创造力',value:7.8,max:10}]},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'孩子在宜人性与同伴信任维度表现突出,说明其社会性发展良好,建议继续提供稳定的同伴交往场景。注意力百分位 68 略低于认知整体水平,可在家庭学习中引入"分段专注 + 即时反馈"的训练方式,每次专注时长从 15 分钟起步逐步延长。父亲维度的沟通与亲近得分相对偏低,建议增加父子单独相处的高质量陪伴时间。焦虑分项 6/15 处于中等水平,可通过睡前情绪复盘帮助孩子外化压力。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'wisdom',code:'B4',name:'智维度',desc:'认知与发展评估 · wisdom',
|
|
|
+ total:82,percentile:76,level:'A',date:'2026-10-18',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'认知能力',note:'推理 / 空间 / 加工速度',maxLabel:true,items:[
|
|
|
+ {label:'推理能力',value:88,max:100},{label:'空间能力',value:76,max:100},{label:'加工速度',value:71,max:100}]},
|
|
|
+ {type:'bars',title:'自我概念',maxLabel:true,items:[
|
|
|
+ {label:'学业自我',value:7.6,max:10},{label:'身体自我',value:7.1,max:10},{label:'社会自我',value:8.0,max:10},{label:'情绪自我',value:6.8,max:10}]},
|
|
|
+ {type:'bars',title:'成长型思维',maxLabel:true,items:[
|
|
|
+ {label:'努力信念',value:8.2,max:10},{label:'挑战接纳',value:7.3,max:10},{label:'失败归因',value:6.4,max:10}]},
|
|
|
+ {type:'bars',title:'自驱力',maxLabel:true,items:[
|
|
|
+ {label:'自主性',value:7.8,max:10},{label:'胜任感',value:7.2,max:10},{label:'坚持性',value:6.6,max:10}]},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'推理能力百分位 88 是显著优势,适合提供开放性、探究式的学习任务(如科学实验、编程启蒙)。加工速度 71 相对偏弱,在限时测验场景中可能吃亏,建议日常做"限时但不计分"的练习降低速度焦虑。失败归因得分 6.4 偏低,孩子容易把挫折归为能力不足,家长反馈时应更多描述过程与策略而非评价天赋。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'cognition',code:'A1',name:'儿童核心认知',desc:'认知六维评估 · cognition',
|
|
|
+ total:82,percentile:78,level:'A',date:'2026-10-12',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'认知能力',note:'六维百分位(P50 为同龄中位)',maxLabel:true,items:[
|
|
|
+ {label:'感知觉',value:85,max:100},{label:'注意力',value:72,max:100},{label:'记忆力',value:80,max:100},
|
|
|
+ {label:'推理能力',value:88,max:100},{label:'空间能力',value:76,max:100},{label:'加工速度',value:69,max:100}]},
|
|
|
+ {type:'bars',title:'认知能力',note:'明细 · 灰线为同龄 P50',maxLabel:true,items:[
|
|
|
+ {label:'感知觉',value:85,max:100,ref:50},{label:'注意力',value:72,max:100,ref:50},
|
|
|
+ {label:'记忆力',value:80,max:100,ref:50},{label:'推理能力',value:88,max:100,ref:50},
|
|
|
+ {label:'空间能力',value:76,max:100,ref:50},{label:'加工速度',value:69,max:100,ref:50}]},
|
|
|
+ {type:'two',title:'优势与待提升',good:['推理能力(88)','感知觉(85)','记忆力(80)'],warn:['加工速度(69)','注意力(72)']},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'整体认知水平位于同龄前 22%,推理与感知觉是双优势维度。加工速度是唯一低于 P50+20 的维度,表现为信息摄取与反应偏慢,建议通过速读、视听反应类小游戏做专项训练,每次 10 分钟、每周 4 次。注意力 72 尚可,但与推理能力的落差提示"会做但不够稳",考试场景下易因分心丢分,可配合番茄钟与错题归因习惯。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'learning',code:'B3',name:'核心学习能力',desc:'执行功能 · 动机 · 策略 · learning',
|
|
|
+ total:74,percentile:70,level:'B',date:'2026-10-15',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'执行功能',note:'百分位',maxLabel:true,items:[
|
|
|
+ {label:'抑制控制',value:68,max:100},{label:'工作记忆',value:74,max:100},{label:'认知灵活性',value:71,max:100}]},
|
|
|
+ {type:'bars',title:'学习动机',note:'十分制',maxLabel:true,items:[
|
|
|
+ {label:'深层动机',value:7.2,max:10},{label:'表面动机',value:5.4,max:10},{label:'自我效能感',value:6.8,max:10}]},
|
|
|
+ {type:'bars',title:'学习策略',note:'十分制',maxLabel:true,items:[
|
|
|
+ {label:'深层方法与策略',value:6.1,max:10},{label:'表面方法与策略',value:5.8,max:10},{label:'学习自我调节',value:5.2,max:10}]},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'执行功能三项均在 68-74 的中上区间,工作记忆相对最好,能支撑多步指令的完成。深层动机 7.2 高于表面动机 5.4,说明孩子 intrinsic 学习兴趣健康,应减少外在奖励依赖。学习自我调节 5.2 是三项策略中最低,表现为计划性差、不会复盘,建议引入"学习计划表 + 周回顾"双件套,家长只做陪伴不做代劳。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'behavior',code:'B2',name:'儿童自我与家庭教养',desc:'自我概念 · 行为 · 家庭环境 · behavior',
|
|
|
+ total:76,percentile:68,level:'B',date:'2026-10-16',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'自我概念',note:'六维 · 十分制',maxLabel:true,items:[
|
|
|
+ {label:'行为表现',value:7.5,max:10},{label:'能力与学校',value:6.8,max:10},{label:'躯体外貌',value:7.2,max:10},
|
|
|
+ {label:'情绪状态',value:6.1,max:10},{label:'合群',value:7.8,max:10},{label:'幸福与满足',value:7.0,max:10}]},
|
|
|
+ {type:'bars',title:'行为表现',note:'八维 · 十分制(多动/刻板/拖延为反向计分)',maxLabel:true,items:[
|
|
|
+ {label:'品行',value:8.2,max:10},{label:'情绪',value:6.4,max:10},{label:'学习',value:6.0,max:10},{label:'社交',value:7.6,max:10},
|
|
|
+ {label:'生活习惯',value:6.8,max:10},{label:'多动倾向',value:4.5,max:10},{label:'刻板行为',value:3.2,max:10},{label:'拖延行为',value:5.6,max:10}]},
|
|
|
+ {type:'bars',title:'家庭环境',note:'十维 · 十分制',maxLabel:true,items:[
|
|
|
+ {label:'亲密度',value:7.2,max:10},{label:'情感表达',value:6.4,max:10},{label:'矛盾性',value:4.1,max:10},
|
|
|
+ {label:'独立性',value:6.8,max:10},{label:'成就性',value:7.0,max:10},{label:'文化性',value:6.2,max:10},
|
|
|
+ {label:'娱乐性',value:6.6,max:10},{label:'道德宗教',value:6.9,max:10},{label:'组织性',value:7.3,max:10},{label:'控制性',value:5.8,max:10}]},
|
|
|
+ {type:'text',title:'教养建议',collapsible:true,content:'合群 7.8 与品行 8.2 是孩子的社交与品行优势,同伴关系稳定。刻板行为 3.2、多动倾向 4.5 均处低位,无需过度担忧。家庭环境中"情感表达 6.4"与"控制性 5.8"是两处可优化点:控制性偏高叠加情感表达偏弱,容易让孩子在遇到挫折时不主动求助,建议家长每天固定 10 分钟"只倾听不给建议"的对话时段。学习维度 6.0 与自我概念中的"能力与学校 6.8"相互印证,可通过降低比较、强调进步来提升学业自我效能。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'career',code:'B6',name:'职业发展',desc:'兴趣 · 多元智能 · 价值观 · career',
|
|
|
+ total:80,percentile:74,level:'A',date:'2026-10-20',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'职业兴趣',note:'Holland 六型 · 百分位',maxLabel:true,items:[
|
|
|
+ {label:'艺术型',value:72,max:100},{label:'社会型',value:85,max:100},{label:'企业型',value:63,max:100},
|
|
|
+ {label:'常规型',value:55,max:100},{label:'现实型',value:48,max:100},{label:'研究型',value:78,max:100}]},
|
|
|
+ {type:'bars',title:'多元智能',note:'1-15 分制',maxLabel:true,items:[
|
|
|
+ {label:'内省智能',value:12,max:15},{label:'空间智能',value:10,max:15},{label:'音乐智能',value:8,max:15},{label:'人际智能',value:13,max:15},
|
|
|
+ {label:'自然观察',value:9,max:15},{label:'运动智能',value:7,max:15},{label:'语言智能',value:11,max:15},{label:'逻辑智能',value:12,max:15}]},
|
|
|
+ {type:'bars',title:'职业价值观',maxLabel:true,items:[
|
|
|
+ {label:'成就感',value:8.4,max:10},{label:'助人',value:8.8,max:10},{label:'独立性',value:7.2,max:10},{label:'创造性',value:8.1,max:10}]},
|
|
|
+ {type:'rec',title:'适配方向',note:'基于兴趣 × 智能 × 价值观',items:[
|
|
|
+ {label:'教育 / 培训',hot:true},{label:'心理咨询',hot:true},{label:'内容创作'},{label:'科研'},{label:'公共关系'}]},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'社会型 85 与人际智能 13 形成强共振,叠加"助人"价值观 8.8,指向明显的服务与教育导向。研究型 78 与逻辑智能 12、内省智能 12 构成第二优势轴,适合做需要深度思考的工作。现实型 48 与运动智能 7 是相对短板,动手操作类活动需更多鼓励而非回避。建议在中学阶段提供志愿服务、同伴辅导类实践机会,让优势轴在真实场景中得到验证。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'campus',code:'C1',name:'校园标准版',desc:'认知 · 人格 · 自驱 · 自我概念 · campus',
|
|
|
+ total:79,percentile:73,level:'B',date:'2026-10-19',
|
|
|
+ blocks:[
|
|
|
+ {type:'radar',title:'认知能力',note:'六维百分位',maxLabel:true,items:[
|
|
|
+ {label:'感知觉',value:83,max:100},{label:'注意力',value:70,max:100},{label:'记忆力',value:79,max:100},
|
|
|
+ {label:'推理能力',value:84,max:100},{label:'空间能力',value:74,max:100},{label:'加工速度',value:68,max:100}]},
|
|
|
+ {type:'radar',title:'大五人格',note:'1-5 分制',maxLabel:true,items:[
|
|
|
+ {label:'开放性',value:4.0,max:5},{label:'宜人性',value:4.3,max:5},{label:'责任心',value:3.6,max:5},
|
|
|
+ {label:'外倾性',value:3.2,max:5},{label:'神经质',value:2.7,max:5}]},
|
|
|
+ {type:'bars',title:'自驱力',note:'三分维度 · 十分制',maxLabel:true,items:[
|
|
|
+ {label:'自主性',value:6.8,max:10},{label:'胜任感',value:7.2,max:10},{label:'归属感',value:7.6,max:10}]},
|
|
|
+ {type:'radar',title:'自我概念',note:'六维 · 十分制',maxLabel:true,items:[
|
|
|
+ {label:'行为表现',value:7.4,max:10},{label:'能力与学校',value:6.9,max:10},{label:'躯体外貌',value:7.0,max:10},
|
|
|
+ {label:'情绪状态',value:6.3,max:10},{label:'合群',value:7.9,max:10},{label:'幸福与满足',value:7.1,max:10}]},
|
|
|
+ {type:'text',title:'校园适应建议',collapsible:true,content:'归属感 7.6 与合群 7.9 说明孩子在学校的人际关系适应良好,是校园适应的保护性因素。责任心 3.6 与加工速度 68 是需要关注的两处:前者影响作业完成的一致性,后者影响课堂与考试的节奏,建议家校配合建立"作业清单 + 时间盒"机制。神经质 2.7 处于低位,情绪稳定性好。'}
|
|
|
+ ]
|
|
|
+},
|
|
|
+{
|
|
|
+ id:'adolescent',code:'B5',name:'青春期挑战',desc:'情绪 · 压力 · 人际 · 生活节律 · adolescent',
|
|
|
+ total:71,percentile:64,level:'C',date:'2026-10-22',
|
|
|
+ blocks:[
|
|
|
+ {type:'bars',title:'情绪调节',note:'1-7 分制',maxLabel:true,items:[
|
|
|
+ {label:'认知重评',value:5.2,max:7},{label:'表达抑制',value:4.6,max:7}]},
|
|
|
+ {type:'bars',title:'学业压力',note:'压力源五维 · 1-5 分制',maxLabel:true,items:[
|
|
|
+ {label:'学业负担',value:3.4,max:5},{label:'家庭期望',value:3.8,max:5},{label:'师生关系',value:2.6,max:5},
|
|
|
+ {label:'自我期望',value:4.1,max:5},{label:'同伴竞争',value:3.2,max:5}]},
|
|
|
+ {type:'bars',title:'人际关系',note:'四维 · 1-5 分制',maxLabel:true,items:[
|
|
|
+ {label:'母亲',value:4.2,max:5},{label:'父亲',value:3.9,max:5},{label:'师生',value:3.4,max:5},{label:'同伴',value:4.0,max:5}]},
|
|
|
+ {type:'radar',title:'社交能力',note:'五维 · 1-5 分制',maxLabel:true,items:[
|
|
|
+ {label:'主动交往',value:3.6,max:5},{label:'情感支持',value:4.1,max:5},{label:'情感表达',value:3.5,max:5},
|
|
|
+ {label:'表达影响',value:3.8,max:5},{label:'冲突解决',value:3.3,max:5}]},
|
|
|
+ {type:'duration',title:'生活节律',note:'睡眠 / 运动 / 网络',items:[
|
|
|
+ {label:'睡眠',value:7.2,unit:'h/天',status:'warn',note:'偏少'},
|
|
|
+ {label:'运动',value:45,unit:'min/天',status:'ok',note:'达标'},
|
|
|
+ {label:'网络',value:3.5,unit:'h/天',status:'bad',note:'偏多'}]},
|
|
|
+ {type:'compass',title:'人际指南针',note:'圆心为自我,点越靠近圆心表示关系越紧密。当前同伴与母亲维度最紧密,师生维度距离最远。',
|
|
|
+ items:[
|
|
|
+ {label:'母亲',value:4.2,max:5},{label:'父亲',value:3.9,max:5},
|
|
|
+ {label:'同伴',value:4.0,max:5},{label:'师生',value:3.4,max:5}]},
|
|
|
+ {type:'text',title:'成长建议',collapsible:true,content:'自我期望 4.1 是全部压力源中最高的一项,说明压力主要来自内部而非外部,需警惕完美主义倾向。网络使用 3.5 小时/天明显偏多,且睡眠仅 7.2 小时,两者高度相关——建议先从不带电子设备进卧室这一条规则开始,而不是全面禁网。表达抑制 4.6 偏高、认知重评 5.2 尚可,孩子更倾向于憋住情绪而非重新解读,可通过写情绪日记逐步建立重评习惯。师生关系 3.4 与社交能力中的冲突解决 3.3 均为相对短板,可鼓励孩子主动向老师提问,从低风险的学业求助开始练习。'}
|
|
|
+ ]
|
|
|
+}
|
|
|
+];
|
|
|
+
|
|
|
+/* ===================== 渲染 ===================== */
|
|
|
+var tabsEl=document.getElementById('tabs'), screenEl=document.getElementById('screen');
|
|
|
+var stageTitle=document.getElementById('stageTitle'), stageDesc=document.getElementById('stageDesc');
|
|
|
+var activeId=REPORTS[0].id;
|
|
|
+
|
|
|
+function buildTabs(){
|
|
|
+ tabsEl.innerHTML = REPORTS.map(function(r){
|
|
|
+ return '<button class="tab'+(r.id===activeId?' active':'')+'" data-id="'+r.id+'">'
|
|
|
+ +'<span class="tab-code">'+r.code+'</span>'
|
|
|
+ +'<span><span class="tab-name">'+r.name+'</span><br><span class="tab-desc">'+r.desc.split(' · ')[0]+'</span></span>'
|
|
|
+ +'</button>';
|
|
|
+ }).join('');
|
|
|
+ tabsEl.querySelectorAll('.tab').forEach(function(b){
|
|
|
+ b.addEventListener('click',function(){ activeId=b.getAttribute('data-id'); buildTabs(); render(); });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function render(){
|
|
|
+ var r=REPORTS.filter(function(x){return x.id===activeId;})[0];
|
|
|
+ var uid=0;
|
|
|
+ var h='';
|
|
|
+
|
|
|
+ /* Hero */
|
|
|
+ h+='<div class="hero"><div class="hero-c1"></div><div class="hero-c2"></div>'
|
|
|
+ +'<div class="hero-top"><div class="hero-name">'+MEMBER.name+'</div>'
|
|
|
+ +'<div class="hero-badges">'
|
|
|
+ +'<span class="bd">'+r.name+'</span>'
|
|
|
+ +'<span class="bd">'+MEMBER.gender+' · '+MEMBER.age+'</span>'
|
|
|
+ +'<span class="bd bd-strong">等级 '+r.level+'</span>'
|
|
|
+ +'<span class="bd">'+r.date+'</span>'
|
|
|
+ +'</div></div>'
|
|
|
+ +'<div class="hero-scores">'
|
|
|
+ +'<div class="hs"><div class="hs-num">'+r.total+'<small>分</small></div><div class="hs-lab">综合得分</div></div>'
|
|
|
+ +'<div class="hs"><div class="hs-num">'+r.percentile+'<small>%</small></div><div class="hs-lab">百分位</div></div>'
|
|
|
+ +'</div>'
|
|
|
+ +'<div class="pct-wrap"><div class="pct-track"><div class="pct-fill" style="width:'+r.percentile+'%"></div></div>'
|
|
|
+ +'<div class="pct-txt">超过 '+r.percentile+'% 的同龄人</div></div>'
|
|
|
+ +'</div>';
|
|
|
+
|
|
|
+ /* Blocks */
|
|
|
+ r.blocks.forEach(function(b){
|
|
|
+ b._id='txt'+(uid++);
|
|
|
+ h+='<div class="card"><div class="card-hd"><div class="card-title">'+b.title+'</div>'
|
|
|
+ +(b.note?'<div class="card-note">'+b.note+'</div>':'')+'</div>'
|
|
|
+ +(RENDER[b.type]?RENDER[b.type](b):'')+'</div>';
|
|
|
+ });
|
|
|
+
|
|
|
+ h+='<div class="foot">本报告由 DAN 测评系统生成,结果仅供成长参考,不构成医学或教育诊断结论。</div>';
|
|
|
+ screenEl.innerHTML=h;
|
|
|
+ stageTitle.textContent=r.code+' · '+r.name;
|
|
|
+ stageDesc.textContent=r.desc;
|
|
|
+
|
|
|
+ /* 展开/收起 */
|
|
|
+ screenEl.querySelectorAll('.more').forEach(function(btn){
|
|
|
+ btn.addEventListener('click',function(){
|
|
|
+ var el=document.getElementById(btn.getAttribute('data-t'));
|
|
|
+ if(el.classList.contains('collapsed')){ el.classList.remove('collapsed'); btn.textContent='收起 ‹'; }
|
|
|
+ else { el.classList.add('collapsed'); btn.textContent='展开全文 ›'; }
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+buildTabs();
|
|
|
+render();
|
|
|
+</script>
|
|
|
+</body>
|
|
|
+</html>
|