Skip to content

Instantly share code, notes, and snippets.

@dongfg
Created August 26, 2025 06:30
Show Gist options
  • Save dongfg/4e05a4ecf70976c441c485b6c4396574 to your computer and use it in GitHub Desktop.
Save dongfg/4e05a4ecf70976c441c485b6c4396574 to your computer and use it in GitHub Desktop.
一键清空CNB云原生开发记录!
// ==UserScript==
// @name 清空云原生开发记录
// @namespace http://tampermonkey.net/
// @version 2025-08-26
// @description 一键清空云原生开发记录!
// @author dongfg
// @match https://cnb.cool/u/*/workspaces
// @icon https://www.google.com/s2/favicons?sz=64&domain=cnb.cool
// @grant none
// ==/UserScript==
(function () {
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function showMessage(msg, duration = 3000) {
const div = document.createElement('div');
div.textContent = msg;
div.style.position = 'fixed';
div.style.bottom = '20px';
div.style.right = '20px';
div.style.background = 'rgba(0,0,0,0.7)';
div.style.color = 'white';
div.style.padding = '10px 15px';
div.style.borderRadius = '5px';
div.style.zIndex = 9999;
div.style.fontSize = '14px';
document.body.appendChild(div);
setTimeout(() => div.remove(), duration); // 自动消失
}
async function getAllPipelineIds() {
const pipelineIds = new Set();
let prevCount = 0;
while (true) {
// 获取当前可见的 pipeline span
const links = document.querySelectorAll('a.flex.items-center.text-blue-600 span');
links.forEach(span => {
const id = span.textContent.trim();
if (id && id.startsWith("cnb-")) pipelineIds.add(id);
});
// 滚动到底部触发加载
window.scrollTo(0, document.body.scrollHeight);
await sleep(1000); // 等待新内容加载
// 如果数量不变,说明加载完成
if (pipelineIds.size === prevCount) break;
prevCount = pipelineIds.size;
}
return Array.from(pipelineIds);
}
async function handleClear() {
const allPipelineIds = await getAllPipelineIds();
console.log("allPipelineIds", allPipelineIds);
const confirmDelete = confirm(`共找到 ${allPipelineIds.length} 个 记录,是否执行删除?`);
if (!confirmDelete) return;
let success = 0;
for (const id of allPipelineIds) {
try {
const response = await fetch(`https://cnb.cool/workspace/delete`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'accept': 'application/vnd.cnb.web+json' },
body: JSON.stringify({ pipelineId: id })
});
const data = await response.json();
if(data.code === 0){
success += 1;
}
console.log(`删除 ${id} 返回:`, data);
} catch (err) {
console.error(`删除 ${id} 出错:`, err);
}
}
showMessage(`成功删除 ${success} 条记录`,3000);
await sleep(3000);
location.reload();
}
function addClearButton() {
// 如果已经存在自定义按钮,直接返回
if (document.querySelector('.t-button__text[data-clear]')) {
return;
}
// 找到重置按钮
const resetSpan = [...document.querySelectorAll('span.t-button__text')]
.find(span => span.textContent.trim() === '重置');
if (!resetSpan) return;
const resetBtn = resetSpan.closest('button');
if (!resetBtn) return;
// 创建新按钮
const newBtn = document.createElement('button');
newBtn.type = 'button';
newBtn.className = 'text-red-600 t-button t-button--theme-default t-button--variant-text t-size-s';
newBtn.innerHTML = '<span class="t-button__text" data-clear>清空</span>';
newBtn.addEventListener('click', () => {
handleClear();
});
// 插到重置按钮后面
resetBtn.insertAdjacentElement('afterend', newBtn);
}
addClearButton();
showMessage("一键清空脚本已加载", 3000);
const mo = new MutationObserver(() => addClearButton());
mo.observe(document.documentElement, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment