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
This commit is contained in:
bigcode
2026-11-02 12:32:18 +08:00
parent 5ff5f9d477
commit ddeeca3293
12 changed files with 866 additions and 46 deletions
+42
View File
@@ -0,0 +1,42 @@
/**
* # 脚本 导入产品归档页 Elementor 模板(legacy elementor_library post 1398)
* 原站 /shop/ 与产品分类归档共用 archive 模板 post 1398(elementor_location=archive):
* - a2ab15c:面包屑 hero(bg #F4F5F8 / padding 0 30 / content 1400)
* - 65176b9:两列(20% WPC 筛选 + 80% 标题 + WooCommerce 商品归档)
* - 61b1990:移动端归档描述(hide_desktop)
* 写入 contents(type=template, slug=shop-archive, meta.elementor),供
* collection 路由以 ElementorRenderer 直出外壳,筛选/商品网格按 widget id 注入。
* 运行:bun scripts/import-shop-template.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");
/** # 函数 从 dump 提取指定 post 的 _elementor_data */
async function extractTemplate(postId: number): Promise<Record<string, unknown>[]> {
const text = await Bun.file(DUMP).text();
const re = new RegExp("\\(\\d+," + postId + ",'_elementor_data','((?:[^'\\\\]|\\\\.)*)'\\)");
const m = text.match(re);
if (!m) throw new Error(`dump 中未找到 post ${postId} 的 _elementor_data`);
const json = m[1]!.replace(/\\'/g, "'").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
const data = JSON.parse(json);
if (!Array.isArray(data)) throw new Error("_elementor_data 不是数组");
return data as Record<string, unknown>[];
}
const elements = await extractTemplate(1398);
const meta = JSON.stringify({ elementor: elements });
const existing = await db`SELECT id FROM contents WHERE slug='shop-archive' AND type='template'`;
if (existing.length) {
await db`UPDATE contents SET meta=${meta}::jsonb, status='published', updated_at=now() WHERE id=${existing[0]!.id}`;
console.log("已更新 shop-archive 模板,contents.id =", existing[0]!.id);
} else {
const inserted = await db`
INSERT INTO contents (type, slug, title, status, meta, legacy_id, published_at)
VALUES ('template', 'shop-archive', 'Shop Archive', 'published', ${meta}::jsonb, 1398, now())
RETURNING id`;
console.log("已插入 shop-archive 模板,contents.id =", inserted[0]!.id);
}
console.log("顶层节:", elements.map((el) => el.id).join(", "));
await db.end();