Files
dusuniot/scripts/import-attribute-term-order.ts
T
bigcode ddeeca3293 v0.10.21: 产品归档页 C1-C4(原站 /shop/ 模板 1398 + WPC 筛选 + WooCommerce 网格)
- 导入 archive 模板 post 1398(slug=shop-archive),/collection/ 用 ElementorRenderer
  直出 hero/两列外壳,按 widget id 注入 ShopFilters/ShopProducts;新增 server function
  解决客户端导航时 loader 打不开 db 的问题
- C1 hero:面包屑 Home / Shop(BreadcrumbWidget + vars.breadcrumb 上下文)
- C2 筛选:12 组属性(term taxonomy 顺序,scripts/import-attribute-term-order.ts);
  长期列表 5 项 + See more,Battery/Operating/Install 默认折叠;URL query 驱动,
  SoM 筛选实测 22 条;顶部 Filters 标题/已选 chips/Clear all
- C3 网格:WooCommerce 归档 DOM(结果计数、orderby、24 卡 4 列、卡片 1:1 图/标题/
  Read more);默认排序导入 products.meta.menu_order(scripts/import-product-menu-order.ts),
  前三个商品与原站一致(DSOM-040R/110R/130N)
- C4 分页:页码/箭头、当前页样式、page2 25–48 条验证
- 修复 Tailwind .columns-4 与 WooCommerce 网格类冲突;app.css 新增 shop 归档 scoped 样式
- 1436 实测:hero 52.8、shop 节 2906.7、筛选区 2798.7、网格 2523.3、卡 257.7×409、
  分页 y2855,与原站逐项一致(±6px 内);bun test 11 pass;版本 0.10.21
2026-11-02 12:32:18 +08:00

113 lines
3.6 KiB
TypeScript
Raw 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.
/**
* # 脚本 导入产品属性术语顺序(对齐原站 /shop/ 筛选列表顺序)
* 原站 WPC 筛选按 wp_term_taxonomy 中的术语顺序展示(取证:pa_product-type 顺序
* SoM → IoT Gateway → Wi-Fi Repeater → Router → Beacon,对应 term_id 756/764/845/846/862;
* pa_cpu 顺序 PX30 → RK3328 → RK3588 → PX30K …)。本项目导入时按字母序写入,需要修复。
* 做法:解析 dump 的 wp_terms(term_id→name)与 wp_term_taxonomy(插入顺序),
* 对每个 pa_<属性 slug>,按顺序把 product_attribute_values.sort 设为序号。
* 运行:bun scripts/import-attribute-term-order.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");
/** # 函数 提取某张表的 INSERT 段文本(支持多段 INSERT) */
function tableInserts(lines: string[], table: string): string[] {
const out: string[] = [];
let buf = "";
let on = false;
for (const l of lines) {
if (l.startsWith(`INSERT INTO \`${table}\` VALUES`)) {
on = true;
buf = l;
} else if (on) {
buf += l;
}
if (on && l.trimEnd().endsWith(";")) {
out.push(buf);
buf = "";
on = false;
}
}
return out;
}
/** # 函数 解析 SQL 值元组 */
function parseTuples(s: string): string[][] {
const out: string[][] = [];
let p = s.indexOf("(");
while (p >= 0 && p < s.length) {
const values: string[] = [];
let cur = "";
let inQ = false;
let esc = false;
let depth = 0;
p++;
for (; p < s.length; p++) {
const ch = s[p]!;
if (esc) { cur += ch; esc = false; continue; }
if (inQ) {
if (ch === "\\") { esc = true; continue; }
if (ch === "'") { inQ = false; continue; }
cur += ch;
continue;
}
if (ch === "'") { inQ = true; continue; }
if (ch === "(") { depth++; cur += ch; continue; }
if (ch === ")") {
if (depth === 0) { values.push(cur); cur = ""; p++; break; }
depth--;
cur += ch;
continue;
}
if (ch === "," && depth === 0) { values.push(cur); cur = ""; continue; }
cur += ch;
}
out.push(values);
p = s.indexOf("(", p);
}
return out;
}
const lines = (await Bun.file(DUMP).text()).split("\n");
// term_id → name
const nameById = new Map<number, string>();
for (const seg of tableInserts(lines, "wp_terms")) {
for (const v of parseTuples(seg)) {
if (v[0]) nameById.set(Number(v[0]), v[1] ?? "");
}
}
console.log("terms:", nameById.size);
// taxonomy → [term names](按 dump 插入顺序)
const byTax = new Map<string, string[]>();
for (const seg of tableInserts(lines, "wp_term_taxonomy")) {
for (const v of parseTuples(seg)) {
const taxonomy = v[2] ?? "";
const termId = Number(v[1]);
if (!taxonomy.startsWith("pa_")) continue;
const name = nameById.get(termId);
if (!name) continue;
const list = byTax.get(taxonomy) ?? [];
list.push(name);
byTax.set(taxonomy, list);
}
}
let updated = 0;
for (const [taxonomy, names] of byTax) {
const attrSlug = taxonomy.slice(3);
for (let i = 0; i < names.length; i++) {
const res = await db`
UPDATE product_attribute_values v SET sort = ${i}
FROM product_attributes a
WHERE v.attribute_id = a.id AND a.slug = ${attrSlug} AND lower(trim(v.value)) = lower(trim(${names[i]!}))`;
updated += res.count;
}
console.log(taxonomy, "→", names.length, "terms");
}
console.log("updated rows:", updated);
await db.end();