()
| 2063 | |
| 2064 | |
| 2065 | function selectCodex2apiService() { |
| 2066 | return new Promise(async (resolve) => { |
| 2067 | const modal = document.getElementById('codex2api-service-modal'); |
| 2068 | const listEl = document.getElementById('codex2api-service-list'); |
| 2069 | const closeBtn = document.getElementById('close-codex2api-modal'); |
| 2070 | const cancelBtn = document.getElementById('cancel-codex2api-modal-btn'); |
| 2071 | const autoBtn = document.getElementById('codex2api-use-auto-btn'); |
| 2072 | |
| 2073 | listEl.innerHTML = '<div style="text-align:center;color:var(--text-muted)">加载中...</div>'; |
| 2074 | modal.classList.add('active'); |
| 2075 | |
| 2076 | let services = []; |
| 2077 | try { |
| 2078 | services = await api.get('/codex2api-services?enabled=true'); |
| 2079 | } catch (e) { |
| 2080 | services = []; |
| 2081 | } |
| 2082 | |
| 2083 | if (services.length === 0) { |
| 2084 | listEl.innerHTML = '<div style="text-align:center;color:var(--text-muted);padding:12px;">暂无已启用的 Codex2API 服务,将自动选择第一个</div>'; |
| 2085 | } else { |
| 2086 | listEl.innerHTML = services.map(s => ` |
| 2087 | <div class="codex2api-service-item" data-id="${s.id}" style=" |
| 2088 | padding: 10px 14px; |
| 2089 | border: 1px solid var(--border); |
| 2090 | border-radius: 8px; |
| 2091 | cursor: pointer; |
| 2092 | transition: background 0.15s; |
| 2093 | display: flex; |
| 2094 | justify-content: space-between; |
| 2095 | align-items: center; |
| 2096 | "> |
| 2097 | <div> |
| 2098 | <div style="font-weight:500;">${escapeHtml(s.name)}</div> |
| 2099 | <div style="font-size:0.8rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</div> |
| 2100 | </div> |
| 2101 | <span class="badge" style="background:var(--primary);color:#fff;font-size:0.7rem;padding:2px 8px;border-radius:10px;">选择</span> |
| 2102 | </div> |
| 2103 | `).join(''); |
| 2104 | |
| 2105 | listEl.querySelectorAll('.codex2api-service-item').forEach(item => { |
| 2106 | item.addEventListener('mouseenter', () => item.style.background = 'var(--surface-hover)'); |
| 2107 | item.addEventListener('mouseleave', () => item.style.background = ''); |
| 2108 | item.addEventListener('click', () => { |
| 2109 | cleanup(); |
| 2110 | resolve({ service_id: parseInt(item.dataset.id) }); |
| 2111 | }); |
| 2112 | }); |
| 2113 | } |
| 2114 | |
| 2115 | function cleanup() { |
| 2116 | modal.classList.remove('active'); |
| 2117 | closeBtn.removeEventListener('click', onCancel); |
| 2118 | cancelBtn.removeEventListener('click', onCancel); |
| 2119 | autoBtn.removeEventListener('click', onAuto); |
| 2120 | } |
| 2121 | function onCancel() { cleanup(); resolve(null); } |
| 2122 | function onAuto() { cleanup(); resolve({ service_id: null }); } |
no test coverage detected