()
| 1965 | // 弹出 Sub2API 服务选择框,返回 Promise<{service_id: number|null}|null> |
| 1966 | // null 表示用户取消,{service_id: null} 表示自动选择 |
| 1967 | function selectSub2ApiService() { |
| 1968 | return new Promise(async (resolve) => { |
| 1969 | const modal = document.getElementById('sub2api-service-modal'); |
| 1970 | const listEl = document.getElementById('sub2api-service-list'); |
| 1971 | const closeBtn = document.getElementById('close-sub2api-modal'); |
| 1972 | const cancelBtn = document.getElementById('cancel-sub2api-modal-btn'); |
| 1973 | const autoBtn = document.getElementById('sub2api-use-auto-btn'); |
| 1974 | |
| 1975 | listEl.innerHTML = '<div style="text-align:center;color:var(--text-muted)">加载中...</div>'; |
| 1976 | modal.classList.add('active'); |
| 1977 | |
| 1978 | let services = []; |
| 1979 | try { |
| 1980 | services = await api.get('/sub2api-services?enabled=true'); |
| 1981 | } catch (e) { |
| 1982 | services = []; |
| 1983 | } |
| 1984 | |
| 1985 | if (services.length === 0) { |
| 1986 | listEl.innerHTML = '<div style="text-align:center;color:var(--text-muted);padding:12px;">暂无已启用的 Sub2API 服务,将自动选择第一个</div>'; |
| 1987 | } else { |
| 1988 | listEl.innerHTML = services.map(s => ` |
| 1989 | <div class="sub2api-service-item" data-id="${s.id}" style=" |
| 1990 | padding: 10px 14px; |
| 1991 | border: 1px solid var(--border); |
| 1992 | border-radius: 8px; |
| 1993 | cursor: pointer; |
| 1994 | transition: background 0.15s; |
| 1995 | display: flex; |
| 1996 | justify-content: space-between; |
| 1997 | align-items: center; |
| 1998 | "> |
| 1999 | <div> |
| 2000 | <div style="font-weight:500;">${escapeHtml(s.name)}</div> |
| 2001 | <div style="font-size:0.8rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</div> |
| 2002 | </div> |
| 2003 | <span class="badge" style="background:var(--primary);color:#fff;font-size:0.7rem;padding:2px 8px;border-radius:10px;">选择</span> |
| 2004 | </div> |
| 2005 | `).join(''); |
| 2006 | |
| 2007 | listEl.querySelectorAll('.sub2api-service-item').forEach(item => { |
| 2008 | item.addEventListener('mouseenter', () => item.style.background = 'var(--surface-hover)'); |
| 2009 | item.addEventListener('mouseleave', () => item.style.background = ''); |
| 2010 | item.addEventListener('click', () => { |
| 2011 | cleanup(); |
| 2012 | resolve({ service_id: parseInt(item.dataset.id) }); |
| 2013 | }); |
| 2014 | }); |
| 2015 | } |
| 2016 | |
| 2017 | function cleanup() { |
| 2018 | modal.classList.remove('active'); |
| 2019 | closeBtn.removeEventListener('click', onCancel); |
| 2020 | cancelBtn.removeEventListener('click', onCancel); |
| 2021 | autoBtn.removeEventListener('click', onAuto); |
| 2022 | } |
| 2023 | function onCancel() { cleanup(); resolve(null); } |
| 2024 | function onAuto() { cleanup(); resolve({ service_id: null }); } |
no test coverage detected