diff --git a/index.html b/index.html
index 871b35b..74e8ab3 100644
--- a/index.html
+++ b/index.html
@@ -1367,7 +1367,7 @@ async function loadUserCredit(id){try{const c=await api('/admin/users/'+id+'/cre
async function openUserDetail(id){const u=adminUsersCache.find(x=>x.id===id);if(!u)return;const next=u.status==='active'?'disabled':'active';$("detailUserName").textContent=u.username;$("detailUserMeta").textContent="#"+u.id+" · "+u.role+" · "+u.status;$("userDetailContent").innerHTML="
账户
角色
"+esc(u.role)+"
状态
"+esc(u.status)+"
加载积分中…
";const drawer = $('adminUserDetail');
const backdrop = $('drawerBackdrop');
if(drawer) drawer.classList.add('active');
- if(backdrop) backdrop.classList.add('active');$("detailReset").onclick=()=>resetUserPassword(id);$("detailToggle").onclick=()=>toggleUser(id,next);try{const c=await api('/admin/users/'+id+'/credits');$("detailCredits").innerHTML="积分
"+c.balance+"
可用 "+c.available+" · 预留 "+c.reserved+" · 下载 "+c.tasks+" 次
";$("detailAdd").onclick=()=>adjustCredits(id,1);$("detailSub").onclick=()=>adjustCredits(id,-1);const l=await api('/admin/users/'+id+'/credits/transactions?limit=30');$("detailCredits").innerHTML+="最近积分流水
"+((l.data||[]).map(t=>"
"+esc(t.type)+" "+(t.amount>=0?'+':'')+t.amount+"
余额 "+t.balanceAfter+" · "+esc(t.reason||'')+" · "+esc(t.createdAt||'')+"
").join('')||"
暂无流水
")+"
"}catch(e){$("detailCredits").textContent=e.message}}
+ if(backdrop) backdrop.classList.add('active');$("detailReset").onclick=()=>resetUserPassword(id);$("detailToggle").onclick=()=>toggleUser(id,next);try{const c=await api('/admin/users/'+id+'/credits');$("detailCredits").innerHTML="积分
"+c.balance+"
可用 "+c.available+" · 预留 "+c.reserved+" · 下载 "+c.tasks+" 次
";$("detailAdd").onclick=()=>adjustCredits(id,1);$("detailSub").onclick=()=>adjustCredits(id,-1);const l=await api('/admin/users/'+id+'/credits/transactions?limit=30');const ledger=document.createElement('div');ledger.className='ledger';ledger.style.marginTop='18px';ledger.innerHTML="最近积分流水
"+((l.data||[]).map(t=>""+esc(t.type)+" "+(t.amount>=0?'+':'')+t.amount+"
余额 "+t.balanceAfter+" · "+esc(t.reason||'')+" · "+esc(t.createdAt||'')+"
").join('')||"暂无流水
");$("detailCredits").appendChild(ledger)}catch(e){$("detailCredits").textContent=e.message}}
async function adjustCredits(id,sign){const raw=prompt(sign>0?'增加多少积分?':'扣除多少积分?','10');if(raw===null)return;const amount=Math.floor(Number(raw));if(!Number.isFinite(amount)||amount<=0){alert('请输入正整数');return}const reason=prompt('调整原因(可选)','管理员调整积分');if(reason===null)return;try{const x=await api('/admin/users/'+id+'/credits',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({amount:sign*amount,reason})});alert('调整成功,当前可用积分:'+x.available);openUserDetail(id);loadAdmin()}catch(e){alert('积分调整失败:'+e.message)}}
async function resetUserPassword(id){const pass=prompt('输入新密码(至少 8 位):');if(pass===null)return;if(pass.length<8){alert('密码至少 8 位');return}try{await api('/admin/users/'+id,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:pass})});alert('密码已重置,该用户的其他登录会话已失效')}catch(e){alert('密码重置失败:'+e.message)}}
async function loadCreditLedger(){try{const u=await api('/admin/users');const users=u.data||[];let total=0;for(const x of users)total+=Number(x.balance)||0;const l=await api('/admin/credits/transactions?limit=100');$('adminCreditSummary').innerHTML='用户'+users.length+'
当前余额'+total+'
流水'+((l.data||[]).length)+'
';$('creditLedger').innerHTML=(l.data||[]).map(t=>'#'+t.userId+' · '+esc(t.type)+' '+(t.amount>=0?'+':'')+t.amount+'
余额 '+t.balanceAfter+' · '+esc(t.reason||'')+' · '+esc(t.createdAt||'')+'
').join('')||'暂无积分流水
'}catch(e){$('adminCreditSummary').textContent=e.message}}