{% from "_macros.html" import th %} {#- five-state badge coloring: warn=needs action, green=healthy, info=paused, red=dead, gray=retired -#} {% set status_badge = {'login_required': 'refused', 'active': 'success', 'cooldown': 'running', 'banned': 'failed', 'retired': 'cancelled'} %} {% set kind_badge = {'login': 'success', 'probe': 'running', 'small_batch': 'running', 'lease_acquired': 'running', 'lease_released': 'no_op', 'lease_expired': 'refused', 'auth_failed': 'failed', 'suspect_yield': 'zero_yield', 'banned': 'failed', 'note': 'no_op'} %} {#- The standing banner rides as an OUT-OF-BAND update of the page slot #auth-alert (spec 警告不重复堆叠): htmx pulls this top-level element out of the swap and refreshes the page-level banner in place, so the warning is never re-rendered inline among the cards below. Rendered unconditionally so a resolved alert clears the slot on the next poll. -#}
{% include "_auth_alert.html" %}

{{ t('身份') }} {{ summary.total }} {{ t('活跃') }} {{ summary.active }} {{ t('需登录') }} {{ summary.login_required }} {{ t('租借中') }} {{ summary.leased }}

{#- 任务分区 (spec: 需登录队列与新建账号表单分属独立分区/卡片): one task per card. The queue comes FIRST — the page banner's 「点下方『登录』」 points at it, so the actionable rows (now carrying their own visible 拉起登录站 buttons, spec 队列行内登录入口可见) sit directly under the warning instead of under the occasional-use registration form. -#}

{{ t('需登录队列') }}

{{ th(t('源')) }}{{ th(t('账号')) }}{{ th(t('自动化')) }}{{ th(t('最近登录')) }}{{ th(t('失败次数')) }}{{ th(t('操作')) }} {% for i in queue %} {% else %} {% endfor %}
{{ i.source }} {{ i.account_alias }} {{ i.automation }} {{ i.last_login_at or t('从未登录') }} {{ i.failure_count }} {#- fields aligned with POST /panel/auth/station/launch: source / account_alias / optional egress_ref -#}
{% if egresses %} {% endif %}
{{ t('队列为空,没有需要登录的身份') }}

{{ t('新建账号') }}

{{ t('身份矩阵') }}

{{ th(t('账号')) }}{{ th(t('状态')) }}{{ th(t('自动化')) }}{{ th(t('最近登录')) }}{{ th(t('最近成功')) }}{{ th(t('连续零产出')) }}{{ th(t('租借')) }} {% for g in groups %} {% for i in g.identities %} {% endfor %} {% else %} {% endfor %}
{{ g.source }} {% if g.auth_profile %}{{ t('认证源') }}{% endif %} {{ g.identities | length }} {{ t('身份') }}
{{ i.account_alias }} {{ i.status }} {% if i.status == 'login_required' %}
{% endif %}
{{ i.automation }} {{ i.last_login_at or '—' }} {{ i.last_success_at or '—' }} {% if i.consecutive_zero_runs %}{{ i.consecutive_zero_runs }}{% else %}0{% endif %} {% if i.leased %}{{ t('租借中') }} {{ i.lease_owner }} {% elif i.lease_expired %}{{ t('租约过期') }} {% else %}—{% endif %}
{{ t('尚无身份') }}

{{ t('事件流') }} {{ t('最近 20 条') }}

{{ th(t('时间')) }}{{ th(t('类型')) }}{{ th(t('身份')) }}{{ th(t('详情')) }}{{ th(t('租借令牌')) }} {% for ev in events %} {% else %} {% endfor %}
{{ ev.created_at or '—' }} {{ ev.kind }} {{ ev.source }} / {{ ev.account_alias }} {{ ev.detail or '—' }} {{ (ev.lease_token or '')[:8] or '—' }}
{{ t('尚无事件') }}

{{ t('登录站') }}

{{ th(t('站')) }}{{ th(t('身份')) }}{{ th(t('状态')) }}{{ th(t('出口')) }}{{ th(t('期限')) }}{{ th(t('操作')) }} {% for stn in stations %} {% include "_station_row.html" %} {% else %} {% endfor %}
{{ t('暂无登录站') }}