#网站/图书馆

😶‍🌫️ 本页面在移动端下显示问题比较大,是使用 dataviewjs 渲染的,与 AI 斗智斗勇了好久也没解决,但页面是可以正常跳转的,大家尽量使用电脑来查看。

读书清单

const folder = "阅读/读书清单";

// 1. 拉取所有符合条件的页面,并按创建时间倒序
let pages = dv.pages(`"${folder}"`)
  .filter(p => p.file.name !== "")
  .filter(p => p["dg-publish"] === true)
  .sort(p => p.file.ctime, 'desc');

// 2. 按 年-月 分组
let monthGroups = {};
for (let p of pages) {
  let dt = p.file.ctime;
  let key = `${dt.year}-${dt.month}`;
  if (!monthGroups[key]) monthGroups[key] = [];
  monthGroups[key].push(p);
}

// 3. 输出
for (let monthKey of Object.keys(monthGroups)) {
  // 月标题
  let [year, month] = monthKey.split('-');
  dv.paragraph(`**${year} 年 ${month} 月:**`);
  
  let groupPages = monthGroups[monthKey];
  // 确定当天列表的顺序(按创建时间排序已在 pages 中)
  let days = [...new Set(groupPages.map(p => p.file.ctime.day))];
  
  for (let day of days) {
    dv.paragraph(`\n${day} 号:`);
    // 当天的文章,按最后修改时间倒序
    let dayPages = groupPages
      .filter(p => p.file.ctime.day === day)
      .sort((a, b) => b.file.mtime.ts - a.file.mtime.ts);
    
    for (let p of dayPages) {
      let filepath = p.file.path.replace(/\$/, "");
      let link = `《${p.file.name}》`;
      let m = p.file.mtime;
      let modified = `${m.year}.${m.month}.${m.day}`;
      dv.paragraph(`${link} 『最后一次修改时间:${modified}』`);
    }
  }
  
  dv.paragraph(""); // 月份之间空行
}

图书书库

// 1. 根目录
const root = "阅读/书库";

// 2. 原始分类映射(末尾不带斜杠)
const pathArray = {
  inbox:       "0_inbox",
  马克思主义:  "A_马克思主义",
  世界哲学:    "B_哲学/B1_世界哲学",
  中国哲学:    "B_哲学/B2_中国哲学",
  心理学:      "B_哲学/B84_心理学",
  社会科学:    "C_社会科学总论",
  政治法律:    "D_政治法律",
  军事:        "E_军事",
  经济学:      "F_经济/F0_经济学",
  农业经济:    "F_经济/F3_农业经济",
  工业经济:    "F_经济/F4_工业经济",
  金融经济:    "F_经济/F8_金融",
  文教科体:    "G_文教科体",
  语言文字:    "H_语言文字",
  世界文学:    "I_文学/I1_世界文学",
  小说:        "I_文学/I2_中国文学/小说",
  诗词:        "I_文学/I2_中国文学/诗词",
  儿童文学:    "I_文学/I2_中国文学/儿童文学",
  艺术:        "J_艺术",
  世界历史:    "K_历史地理/K1_世界史",
  中国历史:    "K_历史地理/K2_中国史",
  人物传记:    "K_历史地理/K81_传记",
  地理:        "K_历史地理/地理",
  自然科学:    "N_自然科学总论",
  数学:        "O_数理化/O1_数学",
  物理:        "O_数理化/O4_物理学",
  天文地球:    "P_天文地球",
  生物:        "Q_生物科学",
  医药卫生:    "R_医药卫生",
  农业:        "S_农业科学",
  电信:        "T_工业技术/TN_电信技术",
  计算机:      "T_工业技术/TP_计算机技术",
  交通:        "U_交通运输",
  航空航天:    "V_航空航天",
  环境安全:    "X_环境安全",
  综合图书:    "Z_综合图书"
};

// 3. 构建前缀分组映射
let groupMap = {}; // prefix -> Set of pages
for (let subpath of Object.values(pathArray)) {
  // 前缀 = 第一个斜杠前的部分
  let prefix = subpath.split('/')[0];
  if (!groupMap[prefix]) groupMap[prefix] = new Set();
  // 查询该子路径下所有带 #书籍 且 dg-publish 为 true 的文件
  const folder = `${root}/${subpath}`;
  let pages = dv.pages(`"${folder}" and #书籍`)
                .filter(p => p["dg-publish"] === true);
  for (let p of pages) {
    groupMap[prefix].add(p);
  }
}

// 4. 按字母顺序遍历每个前缀分组
for (let prefix of Object.keys(groupMap).sort()) {
  const pages = Array.from(groupMap[prefix]);
  if (!pages.length) continue; // 若无内容则跳过

  // 4.1 解析字母与分类名
  const [letter, rawName] = prefix.split('_');
  const className = rawName; // 如 "马克思主义"、"哲学" 等

  // 4.2 区块标题
  dv.header(3, `${letter} 类:${className} 分区`);

  // 4.3 按文件名排序
  pages.sort(p => p.file.name);

  // 4.4 渲染表格
  dv.table(
    ["书名", "标签", "作者", "ISBN"],
    pages.map(p => {
      const fileKey = p.file.path.replace(/\$/, "");
      const link = `《${p.file.name}》`;
      let tags = "";
      if (Array.isArray(p.tags)) {
        tags = p.tags.map(t => `#${t}`).join("、");
      } else if (p.tags) {
        tags = `#${p.tags}`;
      }
      return [
        link,
        tags,
        p.作家 ?? "",
        p.ISBN ?? ""
      ];
    })
  );
}