要不是群聊被问到,我是真没想到竟然还有其他人会也有这样的需求。
前提条件:
- 安装 Query & View 插件。
- 安装番茄工具箱插件。
使用方法效果展示:
将光标放到对应同级的列表项块中,然后使用复制 id-快捷键去复制(段落)块 id。
注意:不能通过块菜单复制。这里的制卡适配的是最底层的段落块 id,递增到同级列表项块制卡。而思源的列表块是列表块、列表项块、段落块嵌套。段落块块标被隐藏,无法通过鼠标选中对应的块菜单。
代码(放入嵌入块中)
//!js
const query = async () => {
let dv = Query.DataView(protyle, item, top);
const docId = dv.useState('docId', '');
const searchResult = dv.useState('search-result', []);
dv.addmd(`**同级列表项快速制卡操作**`);
// 文档ID输入框(3行高度)
const idInput = document.createElement('textarea');
idInput.className = "fn__block b3-text-field";
idInput.placeholder = "输入块ID (如:20250424104910-q34fpnf)";
idInput.rows = 3; // 改为3行高度
idInput.style.fontSize = '22px';
idInput.style.marginBottom = '8px';
idInput.value = docId.value;
dv.addele(idInput);
// 按钮容器(网格布局)
const btnGrid = document.createElement('div');
btnGrid.style.display = 'grid';
btnGrid.style.gridTemplateColumns = 'repeat(2, 1fr)';
btnGrid.style.gap = '8px';
btnGrid.style.marginBottom = '8px';
// 创建按钮(只保留添加、移除和刷新)
const addButton = createButton("添加闪卡");
const removeButton = createButton("移除闪卡");
const refreshButton = createButton("刷新结果");
// 添加到网格
btnGrid.appendChild(addButton);
btnGrid.appendChild(removeButton);
btnGrid.appendChild(refreshButton);
dv.addele(btnGrid);
// 结果容器
const resultContainer = document.createElement('div');
dv.addele(resultContainer);
// 初始渲染结果
updateResults();
// 按钮事件处理
const handleButtonClick = async (action) => {
const blocks = await executeQuery();
if (!blocks) return;
switch(action) {
case 'add':
await tomato_zZmqus5PtYRi.siyuan.addRiffCards(blocks.map(b => b.id));
break;
case 'remove':
await tomato_zZmqus5PtYRi.siyuan.removeRiffCards(blocks.map(b => b.id));
break;
// 移除批量推迟、分散推迟和调整优先级的case分支
}
updateResults();
dv.repaint();
}
refreshButton.onclick = async () => {
await executeQuery();
updateResults();
dv.repaint();
}
// 按钮绑定
addButton.onclick = () => handleButtonClick('add');
removeButton.onclick = () => handleButtonClick('remove');
// 辅助函数:创建按钮
function createButton(text) {
const btn = document.createElement('button');
btn.className = "b3-button";
btn.textContent = text;
btn.style.width = '100%';
btn.style.padding = '8px 0';
return btn;
}
// 辅助函数:执行查询
async function executeQuery() {
const id = idInput.value.trim();
if (!id) {
searchResult([]);
return null;
}
const finalSql = `SELECT * FROM blocks
WHERE parent_id = (
SELECT parent_id FROM blocks
WHERE id = (
SELECT parent_id FROM blocks
WHERE id = '${id}'
)
) AND type = 'i'`;
try {
const blocks = await tomato_zZmqus5PtYRi.siyuan.sql(finalSql);
docId.value = id;
searchResult(blocks);
return blocks;
} catch (error) {
console.error("SQL执行失败:", error);
return null;
}
}
// 辅助函数:获取卡片(保留,但不再用于移除的功能)
async function getCards(blocks) {
const cardMap = await tomato_zZmqus5PtYRi.siyuan.getRiffCardsByBlockIDs(blocks.map(b => b.id));
return [...cardMap.values()].flat();
}
// 辅助函数:更新结果视图
function updateResults() {
resultContainer.innerHTML = '';
if (searchResult().length > 0) {
dv.addlist(searchResult(), {
fullwidth: true,
cols: null
}, resultContainer);
} else {
const emptyMsg = document.createElement('div');
emptyMsg.className = "b3-label";
emptyMsg.textContent = "无查询结果";
emptyMsg.style.textAlign = 'center';
emptyMsg.style.padding = '20px';
emptyMsg.style.opacity = '0.6';
resultContainer.appendChild(emptyMsg);
}
}
dv.render();
}
return query();
致谢
@Frostime 佬提供 querw&view 插件、思源 sql 的入门教程及 sql 小助手提示词。
@player 番茄佬书写并提供制卡/取消制卡的代码。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于