async function viewDevices(){ const dock=document.getElementById('pagerDock'); if(dock) dock.innerHTML=''; const data=await api('/api/admin/devices'); if(data.error){ $('#app').innerHTML='
'+esc(data.error)+'
'; return; } const list=Array.isArray(data.devices)?data.devices:[]; window._autoDevices=list; const tasks=Array.isArray(data.tasks)?data.tasks:[]; window._bindTasks=tasks; const taskById={}; tasks.forEach(t=>{ taskById[t.id]=t; }); const rows=list.map(d=>{ const yes=v=>v?'是':'否'; const enable=d.enabled?'':''; const auth=(d.authorized?'':'')+' '+enable+' '; return ''+esc(d.name||d.id)+'
'+esc(d.id)+'
'+esc(d.model||'-')+'
'+esc(d.serial||'')+'
'+(d.online?pill('running')+' 在线':pill('disabled')+' 离线')+''+(d.enabled?pill('ready')+' 后台开启':pill('disabled')+' 后台停用')+''+((d.task_id?pill('running')+' 执行中':(d.polling?pill('queued')+' 手机领取中':pill('cancelled')+' 手机已停止')))+'Root '+yes(d.root)+'
无障碍 '+yes(d.accessibility)+''+(d.task_id && taskById[d.task_id]?'':(d.task_id?'#'+d.task_id:'-'))+''+(d.authorized?'已授权':'未授权')+''+auth+''; }).join(''); const bar='
下载 auto_google_store'+(data.apk_version?('版本 '+esc(data.apk_version)):'')+''+esc(data.key||'')+'
'; $('#app').innerHTML=bar+'

自动化设备

'+(rows||'')+'
名称机型连接后台手机权限执行中的任务授权
还没有设备连接
'; document.querySelectorAll('[data-dev]').forEach(btn=>btn.onclick=()=>authorizeDevice(btn.dataset.dev, btn.dataset.on==='1')); document.querySelectorAll('[data-en]').forEach(btn=>btn.onclick=()=>enableDevice(btn.dataset.en, btn.dataset.on==='1')); document.querySelectorAll('[data-task]').forEach(btn=>btn.onclick=()=>showBindTask(btn.dataset.task)); document.querySelectorAll('[data-del]').forEach(btn=>btn.onclick=()=>deleteDevice(btn.dataset.del)); } async function authorizeDevice(id, on){ const res=await api('/api/admin/devices/'+encodeURIComponent(id)+'/authorize',{method:'POST',body:JSON.stringify({authorized:on})}); if(res.error) return fail('无法授权', res.error); notice(on?'已授权':'已取消','密钥已下发到在线设备'); viewDevices(); } async function deleteDevice(id){ const ok=await modal({title:'删除设备', message:'删除后这台设备需要重新连接,授权也会清掉。', okText:'删除'}); if(!ok) return; const res=await api('/api/admin/devices/'+encodeURIComponent(id)+'/delete',{method:'POST',body:'{}'}); if(res.error) return fail('无法删除', res.error); notice('已删除',''); viewDevices(); } async function enableDevice(id, on){ const res=await api('/api/admin/devices/'+encodeURIComponent(id)+'/enabled',{method:'POST',body:JSON.stringify({enabled:on})}); if(res.error) return fail('无法更新', res.error); notice(on?'已开启':'已停用','状态已同步到设备'); viewDevices(); } function showBindTask(id){ const t=(window._bindTasks||[]).find(x=>String(x.id)===String(id)); if(!t) return fail('没有任务','任务 #'+id+' 不在当前列表'); const name={queued:'排队', leased:'已领取', paused:'已挂起', done:'已完成', failed:'失败', removed:'已移除'}; modal({title:'绑卡任务 #'+t.id, cancelText:false, okText:'关闭', rows:[ ['账号', t.email||('#'+t.account_id)], ['卡片', (t.card_brand||'')+' 尾号 '+(t.card_last4||'')+' #'+t.card_id], ['国家', t.country||''], ['进度', (name[t.status]||t.status)+(t.error?' · '+t.error:'')], ['设备', t.device_name||t.device_id||'-'], ['创建', fmtTime(t.created_at)], ['领取', fmtTime(t.leased_at)], ['完成', fmtTime(t.finished_at)] ]}); } function showAutoDevice(id){ const d=(window._autoDevices||[]).find(x=>x.id===id); if(!d) return fail('没有设备','设备不在当前列表'); const yes=v=>v?'是':'否'; modal({title:d.name||d.id, cancelText:false, okText:'关闭', rows:[ ['编号', d.id], ['机型', d.model||'-'], ['序列号', d.serial||'-'], ['连接', d.online?'在线':'离线'], ['后台', d.enabled?'开启':'停用'], ['手机', d.polling?'领取中':'已停止'], ['Root', yes(d.root)], ['无障碍', yes(d.accessibility)], ['授权', d.authorized?'已授权':'未授权'], ['任务', d.task_id?('#'+d.task_id):'-'] ]}); }