v0.10.23: 落地页收口(toggle/内嵌模板 27143/posts cards/info-box)+ dev 3311 修复

This commit is contained in:
bigcode
2026-11-02 16:15:14 +08:00
parent 07774c715f
commit 864a737c58
13 changed files with 605 additions and 83 deletions
+50 -5
View File
@@ -4,6 +4,8 @@
* 全部走索引 + 稳定分页,供 Server Function / SSR loader 使用。
*/
import { db } from "~/db";
// 仅类型引用(编译期擦除):避免与渲染器产生运行期循环依赖
import type { ElElement } from "~/components/elementor/Renderer";
import {
contents,
categories,
@@ -119,6 +121,39 @@ export async function getShopTemplate() {
return getPublishedContent("shop-archive", "template");
}
/** # 函数 内嵌 Elementor 模板([elementor-template id="N"] 短代码引用的 post)
* 由 scripts/import-embedded-templates.ts 以 slug=`template-<legacyId>` 落库。
* 参数 legacyId WP 模板 post id(如 27143)
* 返回值 内容行(meta.elementor 为模板元素树);不存在返回 null
*/
export async function getEmbeddedTemplate(legacyId: number) {
return getPublishedContent(`template-${legacyId}`, "template").catch(() => null);
}
/** # 函数 收集 Elementor 文档中 posts widget 的查询并预取文章
* posts widget(skin cards)按 settings.posts_include_term_ids(WP 术语 legacy_id)+
* cards_posts_per_page 查询最新文章;结果以 widget id 为键返回给 ElementorRenderer。
* 参数 elements Elementor 文档(裸元素数组,可含多篇文档拼接后的元素)
* 返回值 widgetId → 文章卡数组
*/
export async function loadPostsWidgetsData(elements: ElElement[] | undefined): Promise<Record<string, PostCardItem[]>> {
const out: Record<string, PostCardItem[]> = {};
const walk = async (els: ElElement[] | undefined) => {
for (const el of els || []) {
if (el.widgetType === "posts" && el.id) {
const st = (el.settings || {}) as Record<string, unknown>;
const termIds = Array.isArray(st.posts_include_term_ids) ? (st.posts_include_term_ids as number[]) : [];
const perPage = Number(st.cards_posts_per_page) || 5;
// 多术语取并集按发布时间倒序(27143:53/54/703)
if (termIds.length) out[el.id] = await listPostsByTermsLegacy(termIds.map(Number), perPage).catch(() => []);
}
if (el.elements?.length) await walk(el.elements);
}
};
await walk(elements);
return out;
}
/** # 类型 产品筛选状态:每个筛选字段已选值列表 */
export type FilterState = Record<string, string[]>;
@@ -598,12 +633,22 @@ export type PostCardItem = {
* 返回值 文章卡数组(标题/摘要/发布时间/特色图/首个分类名)
*/
export async function listPostsByTermLegacy(legacyTermId: number, limit: number) {
const [cat] = await db
return listPostsByTermsLegacy([legacyTermId], limit);
}
/** # 函数 按多个 WP 术语 legacy_id 取最新文章(posts widget 多分类并集)
* Elementor posts widget 的 posts_include_term_ids 可含多个分类,按发布时间倒序
* 取并集(原站落地页 27143:terms 53/54/703 → Blog/Case Study/News,最新 4 篇)。
* 参数 legacyTermIds WP 术语 id 列表;limit 取条数
* 返回值 文章卡数组(去重后按发布时间倒序)
*/
export async function listPostsByTermsLegacy(legacyTermIds: number[], limit: number) {
const catRows = await db
.select({ id: categories.id })
.from(categories)
.where(eq(categories.legacyId, legacyTermId))
.limit(1);
if (!cat) return [] as PostCardItem[];
.where(inArray(categories.legacyId, legacyTermIds));
if (!catRows.length) return [] as PostCardItem[];
const catIds = catRows.map((c) => c.id);
const rows = await db
.select({
slug: contents.slug,
@@ -620,7 +665,7 @@ export async function listPostsByTermLegacy(legacyTermId: number, limit: number)
and(
eq(contents.type, "post"),
eq(contents.status, "published"),
sql`EXISTS (SELECT 1 FROM content_terms ct WHERE ct.content_id=${contents.id} AND ct.category_id=${cat.id})`,
sql`EXISTS (SELECT 1 FROM content_terms ct WHERE ct.content_id=${contents.id} AND ct.category_id IN (${sql.join(catIds.map((id) => sql`${id}`), sql`, `)}))`,
),
)
.orderBy(desc(contents.publishedAt))