feat(blog): tags 空时从 SEO 关键词自动 fallback 前 3 个
admin 编辑页暂无 tags 输入框,保存的文章 tags 为空,前端卡片无小标签显示 (对比老文章都有"草原穿搭/旅拍穿搭"等 tag)。 在 server/utils/article-helpers.js 加 resolveTagsWithFallback: - 前端传 tags 数组(非空)→ 按前端 - 否则从 seoKeywords 用 [,,、] 拆分取前 3 个 - 都没有 → [] POST/PUT 均接入。PUT 时用户改 seoKeywords 也会同步刷新 tags。
这个提交包含在:
父节点
61c94b741e
当前提交
9a0afb7cce
@ -1,5 +1,6 @@
|
|||||||
import { useDB, schema } from '../../utils/db.js'
|
import { useDB, schema } from '../../utils/db.js'
|
||||||
import { requireAdmin } from '../../utils/auth.js'
|
import { requireAdmin } from '../../utils/auth.js'
|
||||||
|
import { resolveTagsWithFallback } from '../../utils/article-helpers.js'
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
requireAdmin(event)
|
requireAdmin(event)
|
||||||
@ -21,7 +22,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
type: body.type || 'news',
|
type: body.type || 'news',
|
||||||
coverImage: body.coverImage || null,
|
coverImage: body.coverImage || null,
|
||||||
author: body.author || '呼籁旅行',
|
author: body.author || '呼籁旅行',
|
||||||
tags: JSON.stringify(Array.isArray(body.tags) ? body.tags : []),
|
tags: JSON.stringify(resolveTagsWithFallback(body)),
|
||||||
seoTitle: body.seoTitle || null,
|
seoTitle: body.seoTitle || null,
|
||||||
seoDesc: body.seoDesc || null,
|
seoDesc: body.seoDesc || null,
|
||||||
seoKeywords: body.seoKeywords || null,
|
seoKeywords: body.seoKeywords || null,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { useDB, schema } from '../../../utils/db.js'
|
import { useDB, schema } from '../../../utils/db.js'
|
||||||
import { requireAdmin } from '../../../utils/auth.js'
|
import { requireAdmin } from '../../../utils/auth.js'
|
||||||
|
import { resolveTagsWithFallback } from '../../../utils/article-helpers.js'
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
requireAdmin(event)
|
requireAdmin(event)
|
||||||
@ -18,10 +19,16 @@ export default defineEventHandler(async (event) => {
|
|||||||
if (body.category !== undefined) updateData.category = body.category
|
if (body.category !== undefined) updateData.category = body.category
|
||||||
if (body.coverImage !== undefined) updateData.coverImage = body.coverImage
|
if (body.coverImage !== undefined) updateData.coverImage = body.coverImage
|
||||||
if (body.author !== undefined) updateData.author = body.author
|
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.seoTitle !== undefined) updateData.seoTitle = body.seoTitle
|
||||||
if (body.seoDesc !== undefined) updateData.seoDesc = body.seoDesc
|
if (body.seoDesc !== undefined) updateData.seoDesc = body.seoDesc
|
||||||
if (body.seoKeywords !== undefined) updateData.seoKeywords = body.seoKeywords
|
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
|
if (body.published !== undefined) updateData.published = body.published ? 1 : 0
|
||||||
|
|
||||||
db.update(schema.articles)
|
db.update(schema.articles)
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户