Files
dusuniot/scripts/repair-content-terms.ts
bigcode a7614e5485 v0.10.19: G2 页脚 Footer 一比一复刻(原站 elementor_library post 58)
- 导入脚本 scripts/import-footer-template.ts:从 legacy dump 提取 post 58 的 _elementor_data
  写入 contents(type=template, slug=footer),并按线上 post-58.css/DOM 补齐快照后改动
  (f95e22e Google Preferred Source、405d251 width:auto、2481635 桌面外距)
- Layout/getLayoutData 下发 footerDoc,Footer 改用 ElementorRenderer 直出原模板,
  短代码按 widget id 注入:menu-2 移动端折叠菜单、gtranslate 语言下拉(原生 select.gt_selector)
- Renderer 增强:section html_tag/边框/content_position、column 响应式宽度与
  populated padding/margin(tablet/mobile)、widget 响应式盒模型、icon widget(fixed 返回顶部)、
  icon-list 图标/间距/文字排版与 CSS 变量悬停、image 宽度、divider Elementor DOM、
  text-editor 对齐与 current-date-time 动态年份、shortcode 预渲染上下文
- slim 白名单补齐响应式/图标/动态标签字段;app.css 新增 FA Solid/Regular 字体、
  页脚 scoped 规则、elementor-hidden-* 响应式可见性
- 实测 1436:页脚总高 590.4 与原站全等(列宽/内层列/logo/社交/下拉逐项一致);
  390:56/15/347/337/97/46.4/61 逐项全等;语言切换写 ui_lang cookie;返回顶部回滚 0
- bun test 11 pass;版本 0.10.19
2026-11-02 11:20:29 +08:00

56 lines
2.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* # 脚本 修复 posts 的分类关联(content_terms)
* 背景:导入管线只落了部分文章的分类(609 篇中 548 篇无关联),首页 H18 posts widget
* (按 Blog/News 分类查最新文章)因此查不到数据。原站完整关系在 legacy 镜像
* dusuniot-db-20261029.sql 的 wp_term_relationships INSERT 段中((post_id,term_id,0) 行)。
* 做法:从 dump 提取全部 (wp_post_id, wp_term_id) 对 → 经 contents.legacy_id /
* categories.legacy_id 映射为本库 id → 补插缺失的 content_terms(幂等)。
* 运行:bun scripts/repair-content-terms.ts
*/
import { SQL } from "bun";
const DUMP = "/home/bigcode/data/dev/sites/dusuniot/legacy/dusuniot-db-20261029.sql";
const db = new SQL("postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot");
// 1) 提取 dump 中的关系对
const text = await Bun.file(DUMP).text();
const pairs = new Set<string>();
const re = /\((\d+),(\d+),0\)/g;
for (const m of text.matchAll(re)) {
pairs.add(`${m[1]}:${m[2]}`);
}
console.log("dump 关系对:", pairs.size);
// 2) 本库映射表:legacyId → id
const contents = await db`SELECT id, legacy_id FROM contents WHERE legacy_id IS NOT NULL`;
const contentMap = new Map<number, number>(contents.map((r: { id: number; legacy_id: number }) => [Number(r.legacy_id), Number(r.id)]));
const cats = await db`SELECT id, legacy_id FROM categories WHERE legacy_id IS NOT NULL`;
const catMap = new Map<number, number>(cats.map((r: { id: number; legacy_id: number }) => [Number(r.legacy_id), Number(r.id)]));
// 3) 已有关联集合(幂等)
const existing = await db`SELECT content_id, category_id FROM content_terms`;
const have = new Set(existing.map((r: { content_id: number; category_id: number }) => `${r.content_id}:${r.category_id}`));
// 4) 补插
let inserted = 0;
for (const p of pairs) {
const [wpPost, wpTerm] = p.split(":").map(Number);
const cid = contentMap.get(wpPost);
const tid = catMap.get(wpTerm);
if (!cid || !tid) continue;
if (have.has(`${cid}:${tid}`)) continue;
await db`INSERT INTO content_terms (content_id, category_id) VALUES (${cid}, ${tid})`;
have.add(`${cid}:${tid}`);
inserted++;
}
console.log(`补插 ${inserted} 条 content_terms`);
// 5) 验证:Blog(53)/News(54) 分类下的文章数
const check = await db`
SELECT ca.name, COUNT(*) AS n FROM content_terms ct
JOIN categories ca ON ca.id = ct.category_id AND ca.legacy_id IN (53, 54)
JOIN contents c ON c.id = ct.content_id AND c.type = 'post' AND c.status = 'published'
GROUP BY ca.name`;
console.log("验证:", JSON.stringify(check));
await db.end();