feat: update template

This commit is contained in:
2026-08-19 22:05:49 +08:00
parent 0e674e9d56
commit 5a71093b0c
67 changed files with 2070 additions and 585 deletions

View File

@@ -18,25 +18,25 @@ WITH paginated_posts AS (
updated_at
FROM posts
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2
)
LIMIT $1 OFFSET $2)
-- 第二步:用这极少量的记录去进行 JOIN
SELECT p.*,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
f.file_url AS cover,
f.file_size AS cover_size,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view_count, 0) AS view_count,
COALESCE(
jsonb_agg(
jsonb_build_object(
'id', t.id,
'name', t.name,
'code', t.code
)
ORDER BY t.sort DESC, t.id
) FILTER (WHERE t.id IS NOT NULL),
'[]'::jsonb
) AS tags
jsonb_agg(
jsonb_build_object(
'id', t.id,
'name', t.name,
'code', t.code
)
ORDER BY t.sort DESC, t.id
) FILTER (WHERE t.id IS NOT NULL),
'[]'::jsonb
) AS tags
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
@@ -55,9 +55,10 @@ GROUP BY p.id,
p.created_at,
p.updated_at,
f.file_url,
f.file_size,
c.name,
c.id,
ps.view
ps.view_count
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC;
-- name: CountPosts :one
@@ -66,13 +67,14 @@ FROM posts;
-- name: GetPostByID :one
SELECT p.*,
f.file_url AS cover,
f.file_url AS cover,
f.file_size AS cover_size,
c.name AS category_name,
c.id AS category_id,
COALESCE(
array_agg(pt.tag_id ORDER BY pt.tag_id) FILTER (WHERE pt.tag_id IS NOT NULL),
ARRAY[]::integer[]
) AS tags
array_agg(pt.tag_id ORDER BY pt.tag_id) FILTER (WHERE pt.tag_id IS NOT NULL),
ARRAY []::integer[]
) AS tags
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
@@ -81,6 +83,7 @@ FROM posts p
WHERE p.id = $1
GROUP BY p.id,
f.file_url,
f.file_size,
c.name,
c.id
LIMIT 1;
@@ -88,7 +91,7 @@ LIMIT 1;
-- name: UpdatePost :execrows
UPDATE posts
SET title = coalesce(sqlc.narg('title'), title),
cover_id = coalesce(sqlc.narg('cover_id'), cover_id),
cover_id = CASE WHEN @update_cover_id::boolean THEN @cover_id ELSE cover_id END,
slug = coalesce(sqlc.narg('slug'), slug),
content = coalesce(sqlc.narg('content'), content),
summary = coalesce(sqlc.narg('summary'), summary),
@@ -105,12 +108,30 @@ WHERE id = $1;
-- web -------------------------------------------------------
-- name: GetPublicPostBySlug :one
SELECT p.*,
f.file_url AS cover,
COALESCE(ps.view, 0) AS view
SELECT p.id,
p.title,
p.slug,
p.content,
p.summary,
p.published_at,
f.file_url AS cover,
COALESCE(ps.view_count, 0) AS view_count,
c.code AS category_code,
c.name AS category_name,
COALESCE(t.tags, '[]') AS tags
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON pc.category_id = c.id
LEFT JOIN LATERAL (
SELECT jsonb_agg(
jsonb_build_object('name', tag.name, 'code', tag.code)
) AS tags
FROM post_tag pt
JOIN tags tag ON tag.id = pt.tag_id
WHERE pt.post_id = p.id
) t ON true
WHERE p.slug = $1
AND p.status = 1
AND p.published_at < NOW()
@@ -132,21 +153,22 @@ WITH paginated_posts AS (
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.*,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
c.code AS category_code,
COALESCE(ps.view_count, 0) AS view_count,
COALESCE(
jsonb_agg(
jsonb_build_object(
'id', t.id,
'name', t.name,
'code', t.code
)
ORDER BY t.sort DESC, t.id
) FILTER (WHERE t.id IS NOT NULL),
'[]'::jsonb
) AS tags
jsonb_agg(
jsonb_build_object(
'id', t.id,
'name', t.name,
'code', t.code
)
ORDER BY t.sort DESC, t.id
) FILTER (WHERE t.id IS NOT NULL),
'[]'::jsonb
) AS tags
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
@@ -164,7 +186,8 @@ GROUP BY p.id,
f.file_url,
c.name,
c.id,
ps.view
c.code,
ps.view_count
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC;
-- name: CountPublishedPosts :one
@@ -174,35 +197,90 @@ WHERE status = 1
AND published_at < NOW();
-- name: ListArchives :many
SELECT
p.id,
p.slug,
p.title,
p.published_at,
c."name" AS category_name
FROM
posts p
LEFT JOIN post_category pc ON p.id = pc.post_id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE
p.status = 1
SELECT p.id,
p.slug,
p.title,
p.published_at,
c."name" AS category_name
FROM posts p
LEFT JOIN post_category pc ON p.id = pc.post_id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE p.status = 1
AND p.published_at < NOW()
ORDER BY
p.published_at DESC, p.id DESC;
ORDER BY p.published_at DESC, p.id DESC;
-- name: ListCategoryStats :many
SELECT
c.id,
c.name,
COUNT(p.id) AS post_count
FROM
categories c
LEFT JOIN post_category pc ON c.id = pc.category_id
LEFT JOIN posts p ON p.id = pc.post_id
AND p.status = 1
SELECT c.id,
c.name,
c.code,
COUNT(p.id) AS post_count
FROM categories c
LEFT JOIN post_category pc ON c.id = pc.category_id
LEFT JOIN posts p ON p.id = pc.post_id
AND p.status = 1
AND p.published_at < NOW()
GROUP BY c.id,
c.sort,
c.name,
c.code
ORDER BY c.sort DESC, c.id;
-- name: ListPublishedPostsWithFilters :many
SELECT p.id,
p.title,
p.slug,
p.summary,
p.sort,
p.published_at,
f.file_url AS cover,
c."name" AS category_name,
c.code AS category_code,
COALESCE(t.tags, '[]') AS tags,
COALESCE(ps."view_count", 0) AS view_count
FROM posts p
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN LATERAL (
SELECT jsonb_agg(
jsonb_build_object('name', tag.name, 'code', tag.code)
) AS tags
FROM post_tag pt
JOIN tags tag ON tag.id = pt.tag_id
WHERE pt.post_id = p.id
) t ON true
WHERE
-- 只显示已发布的文章
p.status = 1
AND p.published_at < NOW()
GROUP BY
c.id,
c.sort,
c.name
ORDER BY c.sort DESC, c.id;
AND
-- category code 过滤NULL 或空字符串时不过滤)
(
COALESCE(sqlc.narg('category_code')::text, '') = ''
OR EXISTS (SELECT 1
FROM post_category pc2
JOIN categories c2 ON c2.id = pc2.category_id
WHERE pc2.post_id = p.id
AND c2.code = sqlc.narg('category_code')::text)
)
AND
-- tag code 过滤NULL 或空字符串时不过滤)
(
COALESCE(sqlc.narg('tag_code')::text, '') = ''
OR EXISTS (SELECT 1
FROM post_tag pt2
JOIN tags t2 ON t2.id = pt2.tag_id
WHERE pt2.post_id = p.id
AND t2.code = sqlc.narg('tag_code')::text)
)
ORDER BY p.sort DESC,
p.published_at DESC,
p.id DESC;
-- name: GetPostsForSitemap :many
SELECT slug, created_at, updated_at
FROM posts
WHERE status = 1
AND published_at < NOW()
ORDER BY sort DESC, published_at DESC, id DESC;