+
+
+ ${targets.map(t => `
+
+ `).join('')}
+
+
`;
+ document.body.appendChild(modal);
+ modal.querySelector('#_upload-close').addEventListener('click', () => { modal.remove(); resolve(null); });
+ modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); resolve(null); } });
+ modal.querySelectorAll('button[data-val]').forEach(btn => {
+ btn.addEventListener('click', () => { modal.remove(); resolve(btn.dataset.val); });
+ });
+ });
+
+ if (!choice) return;
+ if (choice === 'cpa') return uploadToCpa(id);
+ if (choice === 'sub2api') return uploadToSub2Api(id);
+ if (choice === 'tm') return uploadToTm(id);
+}
+
// 上传单个账号到CPA
async function uploadToCpa(id) {
const choice = await selectCpaService();
@@ -843,8 +873,8 @@ async function handleBatchUploadCpa() {
const confirmed = await confirm(`确定要将选中的 ${count} 个账号上传到CPA吗?`);
if (!confirmed) return;
- elements.batchUploadCpaBtn.disabled = true;
- elements.batchUploadCpaBtn.textContent = '上传中...';
+ elements.batchUploadBtn.disabled = true;
+ elements.batchUploadBtn.textContent = '上传中...';
try {
const payload = buildBatchPayload();
@@ -908,8 +938,129 @@ async function handleBatchCheckSubscription() {
}
}
+// ============== Sub2API 上传 ==============
+
+// 弹出 Sub2API 服务选择框,返回 Promise<{service_id: number|null}|null>
+// null 表示用户取消,{service_id: null} 表示自动选择
+function selectSub2ApiService() {
+ return new Promise(async (resolve) => {
+ const modal = document.getElementById('sub2api-service-modal');
+ const listEl = document.getElementById('sub2api-service-list');
+ const closeBtn = document.getElementById('close-sub2api-modal');
+ const cancelBtn = document.getElementById('cancel-sub2api-modal-btn');
+ const autoBtn = document.getElementById('sub2api-use-auto-btn');
+
+ listEl.innerHTML = '加载中...
';
+ modal.classList.add('active');
+
+ let services = [];
+ try {
+ services = await api.get('/sub2api-services?enabled=true');
+ } catch (e) {
+ services = [];
+ }
+
+ if (services.length === 0) {
+ listEl.innerHTML = '