diff --git a/public/js/admin.js b/public/js/admin.js index c675b96..7221990 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -489,6 +489,70 @@ }, 9000); })(); + // 通用:复制到剪贴板(有权限限制/兼容降级) + function copyToClipboard(text) { + var t = String(text || ''); + if (!t) { + return Promise.reject(new Error('empty')); + } + + if (navigator && navigator.clipboard && navigator.clipboard.writeText) { + return navigator.clipboard.writeText(t); + } + + return new Promise(function (resolve, reject) { + try { + var ta = document.createElement('textarea'); + ta.value = t; + ta.setAttribute('readonly', 'readonly'); + ta.style.position = 'fixed'; + ta.style.top = '-1000px'; + ta.style.left = '-1000px'; + document.body.appendChild(ta); + ta.select(); + var ok = document.execCommand('copy'); + document.body.removeChild(ta); + ok ? resolve() : reject(new Error('copy_failed')); + } catch (e) { + reject(e); + } + }); + } + + // 批次页:一键复制 run_id(渐进增强) + (function(){ + var btn = qs('[data-action="copy-run-id"][data-run-id]'); + if(!btn){return;} + + btn.addEventListener('click', function(){ + var runId = btn.getAttribute('data-run-id') || ''; + copyToClipboard(runId).then(function(){ + // 复用 toast 容器(若不存在则降级 alert) + try { + var container = qs('[data-role="toast-container"]'); + if(container){ + var t = document.createElement('div'); + t.className = 'toast toast-success'; + t.setAttribute('role','status'); + var c = document.createElement('div'); + c.className = 'toast-content'; + c.textContent = '已复制 run_id:' + runId; + t.appendChild(c); + container.appendChild(t); + setTimeout(function(){ + try{ container.removeChild(t);}catch(e){} + }, 2500); + return; + } + } catch(e) {} + + try { window.alert('已复制 run_id:' + runId); } catch (e) {} + }).catch(function(){ + try { window.alert('复制失败,请手动复制 run_id:' + runId); } catch (e) {} + }); + }); + })(); + // 续费缺订阅治理:订单详情页“绑定订阅ID”输入框,小交互增强: // - 输入后按 Enter 直接提交 // - 自动聚焦,减少点击 diff --git a/resources/views/admin/platform_batches/show.blade.php b/resources/views/admin/platform_batches/show.blade.php index 1f9e98d..54894da 100644 --- a/resources/views/admin/platform_batches/show.blade.php +++ b/resources/views/admin/platform_batches/show.blade.php @@ -39,6 +39,9 @@
diff --git a/tests/Feature/AdminPlatformBatchShowPageCopyRunIdButtonShouldRenderTest.php b/tests/Feature/AdminPlatformBatchShowPageCopyRunIdButtonShouldRenderTest.php new file mode 100644 index 0000000..0fb3aa7 --- /dev/null +++ b/tests/Feature/AdminPlatformBatchShowPageCopyRunIdButtonShouldRenderTest.php @@ -0,0 +1,36 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_batch_show_page_should_render_copy_run_id_button(): void + { + $this->loginAsPlatformAdmin(); + + $runId = 'BAS_COPY_BTN_0001'; + + $html = $this->get('/admin/platform-batches/show?type=bas&run_id=' . $runId) + ->assertOk() + ->getContent(); + + $this->assertStringContainsString('data-action="copy-run-id"', $html); + $this->assertStringContainsString('data-run-id="' . $runId . '"', $html); + $this->assertStringContainsString('复制 run_id', $html); + } +}