Wilson@思源

目 录

表格和数据库联动

see https://ld246.com/article/1741622377103
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(); }; }