3 lines
8.3 KiB
JavaScript
3 lines
8.3 KiB
JavaScript
(function(){'use strict';var root=document.getElementById('app'),apiBase=(window.PK_CONFIG.apiBase||'').replace(/\/$/,''),state={test:null,b:null,result:null,theme:'celebration',sticker:true};function esc(v){return String(v).replace(/[&<>"']/g,function(c){return({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c];});}function toast(m){var e=document.getElementById('toast');e.textContent=m;e.classList.add('show');setTimeout(function(){e.classList.remove('show');},2000);}function req(path,o){o=o||{};var h={'Content-Type':'application/json'},t=localStorage.getItem('rice_token');if(t)h.Authorization='Bearer '+t;return fetch(apiBase+path,{method:o.method||'GET',headers:h,body:o.data?JSON.stringify(o.data):undefined}).then(function(r){return r.json().catch(function(){return{};}).then(function(d){if(!r.ok)throw new Error(d.detail||'请求失败');return d;});});}function login(){if(localStorage.getItem('rice_token'))return Promise.resolve();var id=localStorage.getItem('rice_preview_id')||(Date.now().toString(36)+Math.random().toString(36).slice(2));localStorage.setItem('rice_preview_id',id);return req('/api/v1/auth/xhs',{method:'POST',data:{app_key:'rice',code:'dev:web-'+id}}).then(function(d){localStorage.setItem('rice_token',d.token);});}function error(e){root.innerHTML='<div class="shell empty"><h2>暂时没接上服务</h2><p>'+esc(e.message||e)+'</p><button id="retry" class="button">重试</button></div>';document.getElementById('retry').onclick=home;}function home(){root.innerHTML='<div class="loading">正在淘米…</div>';Promise.all([req('/api/v1/tests/rice'),login().then(function(){return req('/api/v1/me/results?test_slug=rice');})]).then(function(v){state.test=v[0];renderHome(v[1]);}).catch(error);}function renderHome(results){root.innerHTML='<div class="shell"><section class="hero"><div class="label">ONLY RICE · '+state.test.candidate_count+' 强</div><div class="bowl">🍚</div><h1>本命饭<br>终极 PK</h1><p>蛋炒饭、煲仔饭、咖喱饭……每轮二选一,看看谁能成为你唯一的那碗饭。</p><button id="start" class="button">开始选饭 →</button></section><div class="section-head"><strong>我的饭类结果</strong><span class="muted">'+results.length+' 次</span></div>'+(results.length?results.map(function(r,i){return'<button class="result-row" data-i="'+i+'"><span class="medal">#1</span><span><small class="muted">'+new Date(r.completed_at).toLocaleDateString()+'</small><strong>'+esc(r.champion_name)+'</strong></span><span>→</span></button>';}).join(''):'<div class="empty">还没有冠军,第一轮现在开始。</div>')+'<section class="bind"><strong>已有 PK 研究所档案?</strong><p class="muted">在综合版生成绑定码,确认后合并两边历史。</p><input id="code" maxlength="6" placeholder="输入 6 位绑定码"><button id="bind" class="button">确认连接</button></section></div>';document.getElementById('start').onclick=start;root.querySelectorAll('.result-row').forEach(function(el){el.onclick=function(){state.result=results[Number(el.dataset.i)];result();};});document.getElementById('bind').onclick=function(){var code=document.getElementById('code').value.toUpperCase();if(code.length!==6)return toast('请输入 6 位绑定码');req('/api/v1/me/link-code/confirm',{method:'POST',data:{code:code}}).then(function(d){localStorage.setItem('rice_token',d.token);toast('档案已连接');home();}).catch(error);};}function start(){state.b={round:1,pool:state.test.candidates.slice(),index:0,winners:[],eliminated:[],decisions:[]};pair();}function current(){return[state.b.pool[state.b.index],state.b.pool[state.b.index+1]||null];}function pair(){var p=current(),done=state.b.decisions.length,total=state.test.candidates.length-1;root.innerHTML='<div class="shell arena"><div class="arena-top"><span>第 '+state.b.round+' 轮</span><span class="muted">'+done+' / '+total+'</span></div><div class="progress"><span style="width:'+Math.round(done/total*100)+'%"></span></div><h1>只能留下一碗饭。</h1><div class="pair"><button class="choice" data-side="0"><span class="letter">A</span><span class="food">🍚</span><strong class="name">'+esc(p[0].name)+'</strong><span class="hint">选它晋级 ↗</span></button><span class="vs">VS</span><button class="choice" data-side="1"><span class="letter">B</span><span class="food">🍚</span><strong class="name">'+esc(p[1].name)+'</strong><span class="hint">选它晋级 ↗</span></button></div></div>';root.querySelectorAll('.choice').forEach(function(el){el.onclick=function(){choose(p[Number(el.dataset.side)]);};});}function choose(w){var b=state.b,p=current(),l=p[0].id===w.id?p[1]:p[0];b.winners.push(w);b.eliminated.unshift(l);b.decisions.push({round:b.round,left_id:p[0].id,right_id:p[1].id,winner_id:w.id});b.index+=2;if(b.index<b.pool.length&&!b.pool[b.index+1]){b.winners.push(b.pool[b.index]);b.index++;}if(b.index>=b.pool.length){b.pool=b.winners;b.winners=[];b.index=0;b.round++;}if(b.pool.length===1)complete();else pair();}function complete(){var b=state.b,c=b.pool[0],f=b.decisions[b.decisions.length-1],runner=f.left_id===c.id?f.right_id:f.left_id;root.innerHTML='<div class="loading">正在保存你的冠军…</div>';req('/api/v1/tests/rice/runs',{method:'POST',data:{app_key:'rice',champion_id:c.id,runner_up_id:runner,ranking_ids:b.pool.concat(b.eliminated).map(function(i){return i.id;}),decisions:b.decisions}}).then(function(r){state.result=r;result();}).catch(error);}function result(){var r=state.result;root.innerHTML='<div class="shell"><section class="champion"><small>48 种饭的最终冠军</small><h1>'+esc(r.champion_name)+'</h1><p>'+(r.runner_up_name?'决赛击败 '+esc(r.runner_up_name):'一路赢到最后')+'</p></section><div class="result-layout"><canvas id="poster" class="poster" width="750" height="1000"></canvas><aside class="controls"><h2>分享卡片</h2><button class="theme active" data-t="celebration">庆祝派对</button><button class="theme" data-t="editorial">杂志封面</button><button class="theme" data-t="sticker">贴纸手账</button><button id="stick" class="theme">手绘贴纸:开启</button><button id="save" class="button wide">保存 PNG</button><button id="again" class="button wide">再选一次</button></aside></div></div>';draw();root.querySelectorAll('[data-t]').forEach(function(el){el.onclick=function(){state.theme=el.dataset.t;root.querySelectorAll('[data-t]').forEach(function(x){x.classList.remove('active');});el.classList.add('active');draw();};});document.getElementById('stick').onclick=function(){state.sticker=!state.sticker;this.textContent='手绘贴纸:'+(state.sticker?'开启':'关闭');draw();};document.getElementById('save').onclick=function(){var a=document.createElement('a');a.download='我的本命饭-'+r.champion_name+'.png';a.href=document.getElementById('poster').toDataURL('image/png');a.click();toast('分享图已保存');};document.getElementById('again').onclick=start;}function draw(){var c=document.getElementById('poster'),x=c.getContext('2d'),r=state.result,ts={celebration:['#ff6b35','#fffaf4','#25211f','#ffe568'],editorial:['#f3eadf','#201d1b','#fff','#285ee8'],sticker:['#c9f06b','#1e2810','#ff72a7','#fff']},t=ts[state.theme];x.fillStyle=t[0];x.fillRect(0,0,750,1000);x.fillStyle=t[1];x.font='700 24px system-ui';x.fillText('RICE PK / MY FINAL PICK',54,72);x.font='900 58px system-ui';x.fillText('我的本命饭',54,156);x.fillStyle=t[2];x.fillRect(46,205,658,440);x.fillStyle=state.theme==='celebration'?'#fffaf4':t[1];x.font='26px system-ui';x.fillText('48 种饭 · 一路二选一',84,270);x.font='900 '+(r.champion_name.length>7?62:82)+'px system-ui';x.fillText(r.champion_name,84,405);x.fillStyle=t[3];x.fillRect(84,440,Math.min(500,r.champion_name.length*80),18);x.fillStyle=state.theme==='celebration'?'#fffaf4':t[1];x.font='24px system-ui';x.fillText('今天就吃它,不接受反驳。',84,525);x.fillStyle=t[1];x.font='700 25px system-ui';x.fillText('我的 TOP 4',54,720);(r.ranking_names||[]).slice(0,4).forEach(function(n,i){x.font='26px system-ui';x.fillText((i+1)+'. '+n,64,774+i*48);});if(state.sticker){x.fillStyle=t[3];x.beginPath();x.arc(645,125,58,0,Math.PI*2);x.fill();x.fillStyle=t[2];x.font='900 28px system-ui';x.fillText('开饭!',607,134);x.font='52px system-ui';x.fillText('✦',640,700);x.fillText('♡',550,900);}x.fillStyle=t[1];x.font='20px system-ui';x.fillText('保存分享图,看看朋友会选哪一碗',54,956);}document.getElementById('home').onclick=home;home();}());
|
|
|