This commit is contained in:
eric
2026-03-10 08:24:08 -05:00
parent ceb951f50e
commit 095a7fb260
2 changed files with 90 additions and 12 deletions

View File

@@ -264,27 +264,101 @@ export async function POST(request: NextRequest) {
const html = `<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>${esc(title)}</title>
<style>body{font-family:system-ui;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f0f4f8;}h2{color:#333;margin-bottom:8px;}p{color:#64748b;font-size:14px;}img{width:220px;height:220px;margin:20px 0;border:1px solid #e2e8f0;border-radius:8px;background:#fff;}.tip{font-size:12px;color:#94a3b8;margin-top:8px;}</style></head>
<style>
*{box-sizing:border-box;}
body{font-family:system-ui,-apple-system,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);}
.card{background:#fff;border-radius:20px;padding:40px;box-shadow:0 25px 50px -12px rgba(0,0,0,.25);text-align:center;max-width:360px;}
h2{color:#1e293b;margin:0 0 8px;font-size:1.5rem;}
.hint{color:#64748b;font-size:14px;margin-bottom:24px;}
.countdown-wrap{width:220px;height:220px;margin:20px auto;position:relative;}
.countdown-ring{transform:rotate(-90deg);}
.countdown-ring circle{fill:none;stroke-width:6;transition:stroke-dashoffset .5s linear;}
.countdown-ring .bg{stroke:#e2e8f0;}
.countdown-ring .progress{stroke:#22c55e;stroke-linecap:round;}
.countdown-inner{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;}
.countdown-inner img{margin-bottom:4px;}
.countdown-num{font-size:1.1rem;font-weight:700;color:#1e293b;line-height:1;}
.countdown-unit{font-size:10px;color:#94a3b8;}
.tip{font-size:13px;color:#64748b;margin-top:20px;}
.success-wrap{display:none;}
.success-wrap.show{display:block;}
.wait-wrap.hide{display:none;}
.success-icon{font-size:4rem;margin-bottom:16px;animation:scaleIn .4s ease;}
.success-title{font-size:1.25rem;color:#16a34a;font-weight:600;margin-bottom:8px;}
.success-desc{color:#64748b;font-size:14px;margin-bottom:24px;}
.success-countdown{font-size:1.5rem;font-weight:700;color:#667eea;}
@keyframes scaleIn{from{transform:scale(0);opacity:0;}to{transform:scale(1);opacity:1;}}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.7;}}
.pulse{animation:pulse 2s ease-in-out infinite;}
</style></head>
<body>
<h2>${esc(title)}</h2>
<p>${esc(hint)}</p>
<img src="${imgSrc}" alt="支付二维码" />
<p class="tip" id="tip">支付成功后将自动跳转1 分钟内未支付将返回首页</p>
<div class="card">
<div class="wait-wrap" id="waitWrap">
<h2>${esc(title)}</h2>
<p class="hint">${esc(hint)}</p>
<div class="countdown-wrap">
<svg class="countdown-ring" width="220" height="220" viewBox="0 0 220 220">
<circle class="bg" cx="110" cy="110" r="100"/>
<circle class="progress" id="progressCircle" cx="110" cy="110" r="100" stroke-dasharray="628" stroke-dashoffset="0"/>
</svg>
<div class="countdown-inner">
<img src="${imgSrc}" alt="支付二维码" style="width:140px;height:140px;border-radius:8px;background:#fff;"/>
<span class="countdown-num" id="countdownNum">60</span>
<span class="countdown-unit">秒后返回</span>
</div>
</div>
<p class="tip pulse" id="tip">等待支付中...</p>
</div>
<div class="success-wrap" id="successWrap">
<div class="success-icon">✅</div>
<div class="success-title">支付成功</div>
<div class="success-desc">感谢您的支持VIP 权益已开通</div>
<div class="success-countdown" id="successCountdown">10 秒后返回首页</div>
</div>
</div>
<script>
(function(){
var orderId="${orderId}";
var returnUrl="${returnUrl}";
if(!orderId){return;}
var waitWrap=document.getElementById("waitWrap");
var successWrap=document.getElementById("successWrap");
var tip=document.getElementById("tip");
var t=0;
var maxT=30;
var countdownNum=document.getElementById("countdownNum");
var progressCircle=document.getElementById("progressCircle");
var successCountdown=document.getElementById("successCountdown");
var maxT=60;
var left=maxT;
var circumference=2*Math.PI*100;
var countdownTimer=setInterval(function(){
left--;
countdownNum.textContent=left;
progressCircle.style.strokeDashoffset=circumference*(1-left/maxT);
if(left<=0){
clearInterval(countdownTimer);
tip.textContent="支付超时,返回首页";
setTimeout(function(){window.location.href="/";},800);
}
},1000);
function showSuccess(){
clearInterval(countdownTimer);
waitWrap.classList.add("hide");
successWrap.classList.add("show");
var s=10;
var t=setInterval(function(){
s--;
successCountdown.textContent=s+" 秒后返回首页";
if(s<=0){
clearInterval(t);
window.location.href=returnUrl;
}
},1000);
}
function check(){
t++;
if(t>maxT){tip.textContent="支付超时,返回首页";window.location.href="/";return;}
fetch("/api/pay/status?order_id="+encodeURIComponent(orderId))
.then(function(r){return r.json();})
.then(function(d){
if(d.ok&&d.paid){window.location.href=returnUrl;return;}
if(d.ok&&d.paid){showSuccess();return;}
setTimeout(check,2000);
})
.catch(function(){setTimeout(check,2000);});