@@ -7,6 +7,30 @@ let pollTimer = null;
let lastPayType = null ; // 记住当前支付方式,「重新下单」时直接复用
let payHelpShown = false ;
let helpTipStage = 0 ; // 1=30秒提示 2=120秒提示;同阶段不重复覆盖刚点出来的反馈
const PENDING _KEY = 'biliBuyPendingOrder' ;
/** 订单号落本地:关掉页面再回来也能接着查卡,不会「付了钱拿不到码」 */
function savePending ( ) {
try {
localStorage . setItem ( PENDING _KEY , JSON . stringify ( {
orderNo , payType : lastPayType ,
cardTypeId : selected ? selected . id : null , at : Date . now ( )
} ) ) ;
} catch ( e ) { /* 隐私模式下不可用则忽略 */ }
}
function clearPending ( ) {
try { localStorage . removeItem ( PENDING _KEY ) ; } catch ( e ) { }
}
function readPending ( maxAgeMs ) {
try {
const d = JSON . parse ( localStorage . getItem ( PENDING _KEY ) || 'null' ) ;
if ( ! d || ! d . orderNo ) return null ;
if ( ! d . at || Date . now ( ) - d . at > maxAgeMs ) { clearPending ( ) ; return null ; }
return d ;
} catch ( e ) { return null ; }
}
function esc ( s ) {
return String ( s == null ? '' : s ) . replace ( /[&<>"']/g , ( c ) => ( {
@@ -79,6 +103,7 @@ async function createOrder(payType) {
if ( ! res || ! res . ok ) throw new Error ( ( res && res . message ) || '创建订单失败' ) ;
orderNo = res . order . orderNo ;
savePending ( ) ;
status . textContent = ` 订单 ${ orderNo } (¥ ${ res . order . amount } )已创建,正在打开支付页面… ` ;
if ( res . payUrl ) window . open ( res . payUrl , '_blank' ) ;
startPolling ( ) ;
@@ -110,11 +135,13 @@ async function queryOrderOnce() {
if ( res . activated ) {
clearInterval ( pollTimer ) ;
pollTimer = null ;
clearPending ( ) ;
showActivated ( res ) ;
} else if ( res . cardKey ) {
clearInterval ( pollTimer ) ;
pollTimer = null ;
hidePayHelp ( ) ;
clearPending ( ) ;
const status = $ ( 'order-status' ) ;
status . className = 'order-status error' ;
status . innerHTML = '✗ <b>已支付并已发卡</b>,但自动激活未成功(' +
@@ -180,6 +207,30 @@ function hidePayHelp() {
if ( tip ) tip . textContent = '' ;
}
/** 打开购买页时恢复上次未完成的订单:关掉页面也不会「付了钱拿不到码」 */
function resumePending ( ) {
const d = readPending ( 30 * 60 * 1000 ) ;
if ( ! d ) return ;
orderNo = d . orderNo ;
if ( d . payType ) lastPayType = d . payType ;
if ( d . cardTypeId && ! selected ) {
const p = packages . find ( ( x ) => String ( x . id ) === String ( d . cardTypeId ) ) ;
if ( p ) {
selected = p ;
document . querySelectorAll ( '.package' ) . forEach ( ( el ) => {
el . classList . toggle ( 'active' , el . dataset . id === String ( d . cardTypeId ) ) ;
} ) ;
$ ( 'chosen-package' ) . innerHTML = ` 已选商品:<b> ${ esc ( p . name ) } </b> 价格 <b>¥ ${ esc ( p . price ) } </b> ${ esc ( durationText ( p . duration _days ) ) } ` ;
$ ( 'step-pay' ) . hidden = false ;
}
}
$ ( 'order-panel' ) . hidden = false ;
const st = $ ( 'order-status' ) ;
st . className = 'order-status pending' ;
st . textContent = '⏳ 已恢复上次未完成的订单 ' + orderNo + ',正在查询支付结果…' ;
startPolling ( ) ;
}
function wirePayHelp ( ) {
const rf = $ ( 'ph-refresh' ) , rn = $ ( 'ph-renew' ) ;
if ( rf ) rf . addEventListener ( 'click' , async ( ) => {
@@ -266,4 +317,4 @@ $('cb-copy') && $('cb-copy').addEventListener('click', async () => {
} ) ;
wirePayHelp ( ) ;
loadPackages ( ) ;
loadPackages ( ) . then ( resumePending ) ;