From 9a0afb7cce5e19f7b5b598d8f230fcbbe3520649 Mon Sep 17 00:00:00 2001 From: wx <2636507191@qq.com> Date: Mon, 20 Apr 2026 13:54:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(blog):=20tags=20=E7=A9=BA=E6=97=B6?= =?UTF-8?q?=E4=BB=8E=20SEO=20=E5=85=B3=E9=94=AE=E8=AF=8D=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=20fallback=20=E5=89=8D=203=20=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit admin 编辑页暂无 tags 输入框,保存的文章 tags 为空,前端卡片无小标签显示 (对比老文章都有"草原穿搭/旅拍穿搭"等 tag)。 在 server/utils/article-helpers.js 加 resolveTagsWithFallback: - 前端传 tags 数组(非空)→ 按前端 - 否则从 seoKeywords 用 [,,、] 拆分取前 3 个 - 都没有 → [] POST/PUT 均接入。PUT 时用户改 seoKeywords 也会同步刷新 tags。 --- server/api/admin/articles.post.js | 3 ++- server/api/admin/articles/[id].put.js | 9 ++++++++- server/utils/article-helpers.js | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 server/utils/article-helpers.js diff --git a/server/api/admin/articles.post.js b/server/api/admin/articles.post.js index bd9d78c..7ba06f7 100644 --- a/server/api/admin/articles.post.js +++ b/server/api/admin/articles.post.js @@ -1,5 +1,6 @@ import { useDB, schema } from '../../utils/db.js' import { requireAdmin } from '../../utils/auth.js' +import { resolveTagsWithFallback } from '../../utils/article-helpers.js' export default defineEventHandler(async (event) => { requireAdmin(event) @@ -21,7 +22,7 @@ export default defineEventHandler(async (event) => { type: body.type || 'news', coverImage: body.coverImage || null, author: body.author || '呼籁旅行', - tags: JSON.stringify(Array.isArray(body.tags) ? body.tags : []), + tags: JSON.stringify(resolveTagsWithFallback(body)), seoTitle: body.seoTitle || null, seoDesc: body.seoDesc || null, seoKeywords: body.seoKeywords || null, diff --git a/server/api/admin/articles/[id].put.js b/server/api/admin/articles/[id].put.js index 0966fae..bd385d8 100644 --- a/server/api/admin/articles/[id].put.js +++ b/server/api/admin/articles/[id].put.js @@ -1,6 +1,7 @@ import { eq } from 'drizzle-orm' import { useDB, schema } from '../../../utils/db.js' import { requireAdmin } from '../../../utils/auth.js' +import { resolveTagsWithFallback } from '../../../utils/article-helpers.js' export default defineEventHandler(async (event) => { requireAdmin(event) @@ -18,10 +19,16 @@ export default defineEventHandler(async (event) => { if (body.category !== undefined) updateData.category = body.category if (body.coverImage !== undefined) updateData.coverImage = body.coverImage if (body.author !== undefined) updateData.author = body.author - if (body.tags !== undefined) updateData.tags = JSON.stringify(Array.isArray(body.tags) ? body.tags : []) if (body.seoTitle !== undefined) updateData.seoTitle = body.seoTitle if (body.seoDesc !== undefined) updateData.seoDesc = body.seoDesc if (body.seoKeywords !== undefined) updateData.seoKeywords = body.seoKeywords + // tags:前端传了用前端的;没传/空数组时从 seoKeywords fallback(admin 编辑页暂无 tags 输入) + if (body.tags !== undefined) { + updateData.tags = JSON.stringify(resolveTagsWithFallback(body)) + } else if (body.seoKeywords !== undefined) { + // 用户改了 seoKeywords 但没传 tags,同步更新 tags + updateData.tags = JSON.stringify(resolveTagsWithFallback(body)) + } if (body.published !== undefined) updateData.published = body.published ? 1 : 0 db.update(schema.articles) diff --git a/server/utils/article-helpers.js b/server/utils/article-helpers.js new file mode 100644 index 0000000..a09b8be --- /dev/null +++ b/server/utils/article-helpers.js @@ -0,0 +1,8 @@ +// 保存文章时若前端未提供 tags 或 tags 为空,自动从 SEO 关键词拆前 3 个作为展示标签 +// 兼容中/英逗号和顿号。tags 是卡片小标签(展示用),seo_keywords 是搜索引擎 meta 用,二者语义略有差异但在 admin 未提供 tags 输入框前用此兜底 +export function resolveTagsWithFallback(body) { + if (Array.isArray(body.tags) && body.tags.length) return body.tags + const kw = typeof body.seoKeywords === 'string' ? body.seoKeywords.trim() : '' + if (!kw) return [] + return kw.split(/[,,、]/).map(s => s.trim()).filter(Boolean).slice(0, 3) +}