feat(payment): 支持 URL 参数直接传递 JWT 登录
This commit is contained in:
@@ -320,7 +320,7 @@ pub async fn payment_index() -> Result<HttpResponse, AppError> {
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 登录区 -->
|
||||
<!-- 登录区(等待授权) -->
|
||||
<div class="login-section" id="loginSection">
|
||||
<div class="login-card">
|
||||
<div class="login-icon">
|
||||
@@ -330,31 +330,18 @@ pub async fn payment_index() -> Result<HttpResponse, AppError> {
|
||||
<path d="M15.32 8.68a.5.5 0 01.01.85l-1.6 1.28 1.6 1.28a.5.5 0 01-.74.38l-3.6-2.88a.5.5 0 01.01-.85l3.6-2.88a.5.5 0 01.72.38v3.22z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="login-title">微信扫码登录</div>
|
||||
<div class="login-desc">请在微信小程序中<br>点击「网页登录」获取登录码</div>
|
||||
<div class="login-title">等待授权</div>
|
||||
<div class="login-desc" id="loginDesc">请在微信小程序中<br>点击「去授权」完成登录</div>
|
||||
|
||||
<div class="error-msg" id="errorMsg"></div>
|
||||
|
||||
<div class="code-display" id="codeDisplay" style="display:none">
|
||||
<div class="code-label">登录码</div>
|
||||
<div class="code-value" id="codeValue">--</div>
|
||||
<div class="code-hint" id="codeHint">有效期 10 分钟</div>
|
||||
</div>
|
||||
|
||||
<div class="scan-status waiting" id="scanStatus" style="display:none">
|
||||
请在小程序中确认登录
|
||||
</div>
|
||||
|
||||
<button class="btn-login" id="btnGenerate" onclick="generateCode()">
|
||||
获取登录码
|
||||
</button>
|
||||
<button class="btn-login btn-refresh" id="btnRefresh" onclick="generateCode()" style="display:none">
|
||||
重新获取
|
||||
</button>
|
||||
|
||||
<div class="login-note">
|
||||
登录码仅用于本次支付,无需输入账号密码<br>
|
||||
登录成功后可选择套餐进行支付
|
||||
等待小程序授权确认...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -431,58 +418,44 @@ pub async fn payment_index() -> Result<HttpResponse, AppError> {
|
||||
let isPaidActive = false;
|
||||
let paidExpiresAt = null;
|
||||
|
||||
// ---- 页面初始化:检查 URL 中的 code 参数 ----
|
||||
// ---- 页面初始化:检查 URL 中的 code 或 jwt 参数 ----
|
||||
(function initFromUrl() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const urlJwt = params.get('jwt');
|
||||
if (urlJwt) {
|
||||
jwt = urlJwt;
|
||||
checkPaidStatus(urlJwt);
|
||||
return;
|
||||
}
|
||||
const urlCode = params.get('code');
|
||||
if (urlCode) {
|
||||
currentShortCode = urlCode;
|
||||
document.getElementById('codeValue').textContent = currentShortCode;
|
||||
document.getElementById('codeDisplay').style.display = 'block';
|
||||
document.getElementById('scanStatus').style.display = 'block';
|
||||
document.getElementById('scanStatus').className = 'scan-status waiting';
|
||||
document.getElementById('scanStatus').textContent = '等待小程序授权确认...';
|
||||
document.getElementById('btnGenerate').style.display = 'none';
|
||||
document.getElementById('btnRefresh').style.display = 'block';
|
||||
document.getElementById('loginDesc').style.display = 'none';
|
||||
// 启动轮询
|
||||
if (pollTimer) clearInterval(pollTimer);
|
||||
pollTimer = setInterval(pollLoginStatus, 2000);
|
||||
}
|
||||
})();
|
||||
|
||||
// ---- 登录码流程(正式版)----
|
||||
async function generateCode() {
|
||||
hideError();
|
||||
const btn = document.getElementById('btnGenerate');
|
||||
btn.disabled = true;
|
||||
btn.textContent = '正在获取...';
|
||||
})();
|
||||
|
||||
async function checkPaidStatus(token) {
|
||||
try {
|
||||
// 1. 获取登录码
|
||||
const resp = await fetch(API_BASE + '/payment/generate-code');
|
||||
const data = await resp.json();
|
||||
if (!data.code) throw new Error('获取登录码失败');
|
||||
|
||||
currentShortCode = data.code;
|
||||
document.getElementById('codeValue').textContent = currentShortCode;
|
||||
document.getElementById('codeDisplay').style.display = 'block';
|
||||
document.getElementById('scanStatus').style.display = 'block';
|
||||
document.getElementById('scanStatus').className = 'scan-status waiting';
|
||||
document.getElementById('scanStatus').textContent = '请在微信小程序中确认登录';
|
||||
btn.style.display = 'none';
|
||||
document.getElementById('btnRefresh').style.display = 'block';
|
||||
|
||||
// 2. 启动轮询
|
||||
if (pollTimer) clearInterval(pollTimer);
|
||||
pollTimer = setInterval(pollLoginStatus, 2000);
|
||||
} catch(e) {
|
||||
showError('获取登录码失败,请稍后重试');
|
||||
btn.disabled = false;
|
||||
btn.textContent = '重新获取';
|
||||
}
|
||||
const resp = await fetch(API_BASE + '/api/user/profile', {
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
});
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
if (data.success) {
|
||||
isPaidActive = data.data.is_paid_active || false;
|
||||
paidExpiresAt = data.data.paid_expires_at || null;
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
showLoggedIn();
|
||||
}
|
||||
|
||||
// ---- 轮询登录状态(正式流程)----
|
||||
async function pollLoginStatus() {
|
||||
if (!currentShortCode) return;
|
||||
try {
|
||||
@@ -529,16 +502,9 @@ pub async fn payment_index() -> Result<HttpResponse, AppError> {
|
||||
document.getElementById('loginSection').style.display = 'block';
|
||||
document.getElementById('paidSection').style.display = 'none';
|
||||
document.getElementById('packages').style.display = 'none';
|
||||
resetLoginUI();
|
||||
}
|
||||
|
||||
function resetLoginUI() {
|
||||
document.getElementById('codeDisplay').style.display = 'none';
|
||||
document.getElementById('scanStatus').style.display = 'none';
|
||||
document.getElementById('btnGenerate').style.display = 'block';
|
||||
document.getElementById('btnGenerate').disabled = false;
|
||||
document.getElementById('btnGenerate').textContent = '获取登录码';
|
||||
document.getElementById('btnRefresh').style.display = 'none';
|
||||
document.getElementById('loginDesc').style.display = 'block';
|
||||
}
|
||||
|
||||
function showError(msg) {
|
||||
@@ -569,7 +535,7 @@ pub async fn payment_index() -> Result<HttpResponse, AppError> {
|
||||
showError('请先登录');
|
||||
return;
|
||||
}
|
||||
window.location.href = '/payment/page?package=' + selected;
|
||||
window.location.href = '/payment/page?package=' + selected + '&jwt=' + encodeURIComponent(jwt);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user