js
//!js
// 数据库块id
const avBlockId = '20250311063435-9066xpv';
// 表格块id
const tableBlockId = '20250311063452-p03kxva';
// 数据库变更后自动更新延迟,单位是毫秒,默认是1秒,0则不自动更新
// 注意:更新该参数后需要刷新页面才能生效
const autoFreshDelay = 1000;
// 监听数据库变化
observeAvChange();
return query(
"select * from ?",
[fromAv(avBlockId), item],
'',
({ rawData, updateTable, renderSuccess }) => {
let tableData = transformData(rawData);
tableData = toMarkdownTable(tableData);
updateTable(tableBlockId, tableData);
return renderSuccess('更新完成', item);
}
);
function toMarkdownTable(data) {
// 提取所有列名(包括空列 "")
const columns = Array.from(
data.reduce((set, row) => {
Object.keys(row).forEach(key => set.add(key));
return set;
}, new Set())
).sort((a, b) => (a === "" ? -1 : a.localeCompare(b))); // 确保空列 "" 在最前面
// 构造表头行
const headerRow = `| ${columns.map(col => (col === "" ? "" : col)).join(" | ")} |`;
// 构造分隔符行
const separatorRow = `| ${columns.map(() => "---").join(" | ")} |`;
// 构造数据行
const dataRows = data.map(row => {
return `| ${columns.map(col => row[col] || "").join(" | ")} |`;
});
// 拼接所有部分
return [headerRow, separatorRow, ...dataRows].join("\n");
}
function transformData(input) {
// 创建一个 Map 来按横坐标分组
const groupedData = new Map();
// 遍历输入数组,按横坐标分组
input.forEach(item => {
const { 主键, 横坐标, 纵坐标 } = item;
// 如果横坐标不存在于 Map 中,则初始化
if (!groupedData.has(横坐标)) {
groupedData.set(横坐标, { "": 横坐标 });
}
// 将纵坐标和主键添加到对应的横坐标分组中
groupedData.get(横坐标)[纵坐标] = 主键;
});
// 将 Map 转换为数组并返回
return Array.from(groupedData.values());
}
function observeAvChange() {
// 监听av变化,当数据库块被修改时,重新获取数据
if(autoFreshDelay > 0 && !window['__table_observe__' + avBlockId]) {
window['__table_observe__' + avBlockId] = observeDOMChanges(document.querySelector('div[data-node-id="'+avBlockId+'"]'), ()=>{
setTimeout(() => {
item.querySelector('.protyle-action__reload').click();
}, 100);
}, autoFreshDelay, {attributes: false});
}
}
// 监听dom变化
function observeDOMChanges(targetNode, callback, debounceTime = 1000, options = {}) {
// 默认配置
const defaultOptions = {
attributes: true,
childList: true,
subtree: true,
};
// 合并默认配置与传入的配置
const config = Object.assign({}, defaultOptions, options);
// 创建一个观察器实例
const observer = new MutationObserver((mutationsList) => {
// 使用防抖函数确保单位时间内最多只调用一次回调
if(window['__table_observeTimer__' + avBlockId]) {
clearTimeout(window['__table_observeTimer__' + avBlockId]);
}
window['__table_observeTimer__' + avBlockId] = setTimeout(() => {
// 处理变化
callback(mutationsList);
}, debounceTime);
});
// 开始观察目标节点
observer.observe(targetNode, config);
// 返回一个函数,以便在不需要时能够停止观察
return () => {
observer.disconnect();
};
}