Files
digital-psychology/js/decode.js
T
jackyu66gitandCursor 2fb1dfee14 chore: seal Design Vision v1 and monorepo scaffold
Archive the differentiated YuXinGu product docs, AI engineering system,
design contract, and Go/Vue scaffold. Next execution prioritizes Cece-parity
over early innovation (see .ai/product/STRATEGY.md).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 16:00:44 +08:00

211 lines
9.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ---------- 工具 ---------- */
function qp(k){return new URLSearchParams(location.search).get(k);}
function strongestEl(p){return EO.reduce((a,b)=>p[b]>p[a]?b:a,EO[0]);}
function esc(s){return (s||'').replace(/</g,'&lt;');}
/* ---------- 精简 SVG 三角图(核心数字:I,J,K,L → M,N → O ---------- */
function miniPyramid(v){
const base=[v.I,v.J,v.K,v.L], mid=[v.M,v.N], apex=v.O;
const CW=42,CH=40,GY=8,W=CW*4+GY*3,cx=W/2;
function cell(x,y,n,hl){
return '<rect x="'+x+'" y="'+y+'" width="'+CW+'" height="'+CH+'" rx="8" fill="'+(hl?'#C8923A':'#fff8ef')+'" stroke="#e0c48a"/><text x="'+(x+CW/2)+'" y="'+(y+CH/2+5)+'" text-anchor="middle" font-size="17" font-weight="700" fill="'+(hl?'#fff':'#8a6d3b')+'">'+(n!=null?n:'')+'</text>';
}
var s='<svg width="'+W+'" height="'+(CH*3+GY*2)+'" xmlns="http://www.w3.org/2000/svg">';
s+=cell(cx-CW/2,0,apex,true);
s+=cell(cx-CW-GY/2,CH+GY,mid[0])+cell(cx+GY/2,CH+GY,mid[1]);
base.forEach(function(n,i){ s+=cell(i*(CW+GY),(CH+GY)*2,n); });
s+='</svg>';
return s;
}
/* ---------- 今日锦囊 ---------- */
var SEASON_EL={0:'水',1:'水',2:'木',3:'木',4:'木',5:'火',6:'火',7:'火',8:'土',9:'金',10:'金',11:'水'};
var YI_JI={
:{yi:'早睡养肝血 · 舒展拉伸 · 绿色蔬菜',ji:'久坐 · 生闷气 · 熬夜'},
:{yi:'午休15分钟 · 菊花/莲子 · 平心静气',ji:'暴晒 · 辛辣油腻 · 过度兴奋'},
:{yi:'规律三餐 · 健脾山药 · 饭后散步',ji:'思虑过度 · 生冷 · 暴饮暴食'},
:{yi:'滋润养肺 · 白色食物 · 深呼吸',ji:'干燥受凉 · 悲忧 · 剧烈耗气'},
:{yi:'早卧晚起 · 温补黑色食物 · 护腰腹',ji:'受寒 · 过劳 · 惊恐紧张'}
};
function todaySolar(){
var now=new Date(),m=now.getMonth()+1,d=now.getDate();
var cur=ST[0];
for(var i=0;i<ST.length;i++){ var t=ST[i];if(m>t.m||(m===t.m&&d>=t.d)) cur=t; }
return cur;
}
/* ---------- 主渲染 ---------- */
function render(){
var y=+qp('y'),m=+qp('m'),d=+qp('d');
var box=document.getElementById('report');
if(!y||!m||!d||y<1900||y>2100){
box.innerHTML='<div class="err">缺少有效生日参数,请从首页重新进入 🙏</div>';return;
}
document.getElementById('disc').style.display='block';
// === 数字引擎 ===
var v=calc(y,m,d);
var mainNum=v.O;
var person=NUM[mainNum]||{title:'',pos:'',neg:'',job:'',desc:''};
// === 养生引擎(无时辰,默认午时12点) ===
var bz=getBazi(new Date(y,m-1,d),12);
var p5=calc5E(bz);
var strong=strongestEl(p5);
var cst=getConst(p5);
var emo=getEmotion(strong);
// === 今日锦囊 ===
var st=todaySolar();
var sEl=SEASON_EL[new Date().getMonth()];
var yj=YI_JI[sEl];
var paid=localStorage.getItem('jiema_paid')==='1';
box.innerHTML=
'<!-- Part1 数字性格 -->'+
'<div class="card">'+
'<span class="tag tag-num">✨ 数字性格密码</span>'+
'<div class="hex">'+mainNum+'</div>'+
'<div class="p-title">'+mainNum+'号人 · '+esc(person.title)+'</div>'+
'<div class="p-oneline">'+esc((person.desc||'').split(/[。.]/)[0])+'</div>'+
'<div class="pyr">'+miniPyramid(v)+'</div>'+
'<div class="lock '+(paid?'unlocked':'')+'" id="lock-num">'+
'<div class="blur">'+
'<b>天赋优势:</b>'+esc(person.pos)+'<br>'+
'<b>人生课题:</b>'+esc(person.neg)+'<br>'+
'<b>适合方向:</b>'+esc(person.job)+'<br>'+
'<b>能量解读:</b>'+esc(person.desc)+
'</div>'+
'<div class="cover">'+
'<div class="lk-t">🔒 解锁你的完整密码</div>'+
'<div class="lk-d">天赋优势 · 人生课题 · 适合方向 · 12组联合码深度解读</div>'+
'<button class="unlock-btn" onclick="unlock()">¥39.9 立即解锁 →</button>'+
'</div>'+
'</div>'+
'</div>'+
'<!-- Part2 五行体质 -->'+
'<div class="card">'+
'<span class="tag tag-ys">🌿 五行体质画像</span>'+
'<div class="ys-type">'+esc(cst.primary)+'</div>'+
'<div class="ys-dir">核心养护:养'+esc(cst.strong)+' · 需呵护'+esc(cst.weak)+'</div>'+
'<div class="bars">'+
EO.map(function(e){return '<div class="bar-row"><span class="lab" style="color:'+EC[e]+'">'+e+'</span><div class="bar-track"><div class="bar-fill" style="width:'+p5[e]+'%;background:'+EC[e]+'"></div></div><span class="val">'+p5[e]+'%</span></div>';}).join('')+
'</div>'+
'<div class="p-oneline">🎭 情绪画像:'+esc((emo.strength||[]).join(' · '))+'</div>'+
'<div class="lock '+(paid?'unlocked':'')+'" id="lock-ys">'+
'<div class="blur">'+
'<b>体质特征:</b>'+esc(cst.body)+'<br>'+
'<b>调养要点:</b>'+esc(cst.tips)+'<br>'+
'<b>易感倾向:</b>'+esc(cst.diseases)+'<br>'+
'<b>季节风险:</b>'+esc(cst.seasonRisk)+'<br>'+
'<b>食疗方向:</b>'+esc(cst.foodTherapy)+'<br>'+
'<b>作息节律:</b>'+esc(cst.dailyRhythm)+
'</div>'+
'<div class="cover">'+
'<div class="lk-t">🔒 解锁五行体质深度分析</div>'+
'<div class="lk-d">脏腑画像 · 易感倾向 · 食疗 · 运动作息方案</div>'+
'<button class="unlock-btn" onclick="unlock()">¥39.9 立即解锁 →</button>'+
'</div>'+
'</div>'+
'</div>'+
'<!-- Part3 今日养生锦囊(免费) -->'+
'<div class="card jn">'+
'<span class="tag tag-ys">🎯 今日养生锦囊</span>'+
'<div class="st">当前节气:'+st.n+' · 时令 '+sEl+' 当令</div>'+
'<h4>今日调养建议</h4>'+
'<div class="row"><b>宜:</b>'+yj.yi+'</div>'+
'<div class="row"><b>忌:</b>'+yj.ji+'</div>'+
'</div>'+
'<!-- 深度入口 -->'+
'<div class="deep">'+
'<a class="d-num" href="shuzi.html?y='+y+'&m='+m+'&d='+d+'">完整数字报告 →</a>'+
'<a class="d-ys" href="health.html?y='+y+'&m='+m+'&d='+d+'&h=12">完整养生方案 →</a>'+
'</div>'+
'<!-- 契合度(免费给分数) -->'+
'<div class="card">'+
'<span class="tag tag-num">💞 测测你和 TA 的契合度</span>'+
'<div class="mini-form">'+
'<input type="number" id="tY" placeholder="年"><span>年</span>'+
'<input type="number" id="tM" placeholder="月"><span>月</span>'+
'<input type="number" id="tD" placeholder="日"><span>日</span>'+
'<button onclick="matchTest('+y+','+m+','+d+')">测算</button>'+
'</div>'+
'<div id="matchOut"></div>'+
'</div>'+
'<!-- 分享 -->'+
'<div class="card">'+
'<span class="tag tag-num">🦋 分享你的身心密码</span>'+
'<button class="share-btn" onclick="genShare(\''+mainNum+'号人 · '+esc(person.title)+'\',\''+esc(cst.primary)+'\',\'养'+esc(cst.strong)+'\')">📱 生成分享卡片</button>'+
'</div>';
}
/* ---------- 付费墙 ---------- */
function unlock(){
document.getElementById('payModal').classList.add('on');
}
function doUnlock(){
localStorage.setItem('jiema_paid','1');
document.querySelectorAll('.lock').forEach(function(el){el.classList.add('unlocked');});
document.getElementById('payModal').classList.remove('on');
}
/* ---------- 契合度(免费仅分数,深度引导付费/双人报告) ---------- */
function matchTest(y1,m1,d1){
var y=+document.getElementById('tY').value,
m=+document.getElementById('tM').value,
d=+document.getElementById('tD').value;
if(!y||!m||!d){alert('请输入 TA 的完整生日');return;}
var a=calc(y1,m1,d1).O, b=calc(y,m,d).O;
var diff=Math.abs(a-b);
var score=92-diff*6+((a+b)%3)*3;
score=Math.max(60,Math.min(98,score));
document.getElementById('matchOut').innerHTML=
'<div class="match-score">'+score+' 分</div>'+
'<div class="lock" style="margin-top:8px">'+
'<div class="blur">你们在沟通节奏、能量互补、相处课题上的详细解读……</div>'+
'<div class="cover">'+
'<div class="lk-t">🔒 解锁完整契合度解读</div>'+
'<div class="lk-d">关系能量图 · 相处建议 · 沟通指南</div>'+
'<button class="unlock-btn" onclick="alert(\'双人契合度报告 ¥129(模拟)\')">¥129 查看完整解读 →</button>'+
'</div>'+
'</div>';
}
/* ---------- 分享卡片(纯 canvas,无外部库) ---------- */
function genShare(numTitle,constType,ysKey){
var c=document.getElementById('shareCanvas'),g=c.getContext('2d');
var W=c.width,H=c.height;
var grd=g.createLinearGradient(0,0,0,H);
grd.addColorStop(0,'#FF9F80');grd.addColorStop(1,'#FFC8B5');
g.fillStyle=grd;g.fillRect(0,0,W,H);
g.fillStyle='#fff';g.textAlign='center';
g.font='bold 40px sans-serif';g.fillText('愈心解码',W/2,90);
g.font='20px sans-serif';g.fillText('一个生日,读懂身与心',W/2,128);
// 卡片
g.fillStyle='rgba(255,255,255,.95)';
roundRect(g,60,180,W-120,380,24);g.fill();
g.fillStyle='#8a6d3b';g.font='bold 46px sans-serif';
g.fillText(numTitle,W/2,290);
g.fillStyle='#5CB85C';g.font='bold 40px sans-serif';
g.fillText(constType,W/2,390);
g.fillStyle='#666';g.font='24px sans-serif';
g.fillText('养生重点:'+ysKey,W/2,460);
g.fillStyle='#E54D42';g.font='20px sans-serif';
g.fillText('▶ 扫码解锁你的身心密码',W/2,530);
g.fillStyle='#fff';g.font='18px sans-serif';
g.fillText('愈心谷 · 愈见魔方,遇见自己',W/2,H-40);
document.getElementById('shareModal').classList.add('on');
}
function roundRect(g,x,y,w,h,r){
g.beginPath();g.moveTo(x+r,y);g.arcTo(x+w,y,x+w,y+h,r);
g.arcTo(x+w,y+h,x,y+h,r);g.arcTo(x,y+h,x,y,r);g.arcTo(x,y,x+w,y,r);g.closePath();
}
render();