wx 61c94b741e fix(blog): tags 双重编码导致详情页 500 + 上传文件名去中文
问题:
- 管理后台编辑博客保存后,访问 /blog/{slug} 返回 500
- 用户上传封面图后前端不识别/裂图

根因:
1. admin [id].get.js 原样返回 DB 里的 tags 字符串 "[]",编辑页 loadItem
   透传到 form.tags,保存时 JSON.stringify 再编码一次 → DB 写入 '"[]"'。
   公开接口 JSON.parse 后得到字符串 "[]" 而非数组,前端 tags.join(',')
   对字符串调用 → TypeError → SSR 500。
2. 上传接口保留中文文件名(\u4e00-\u9fa5 正则放行),Nginx/Nuxt 静态服务
   对含中文 URL 处理不一致,静态请求 404。

修复:
- admin GET:tags 统一解析为数组返回
- admin POST/PUT:只接受数组,非数组写入空数组
- 公开 /api/content/blog|news:safeParseTags 兼容历史脏数据,
  即使 DB 里是 '"[]"' / 非法 JSON 也保证输出数组
- upload.post.js:safeName 只保留 ASCII 字母数字,去除中文
- scripts/fix-articles-tags.mjs:一次性清理历史双重编码数据
2026-04-20 13:21:04 +08:00

34 行
1.4 KiB
JavaScript

import { eq } from 'drizzle-orm'
import { useDB, schema } from '../../../utils/db.js'
import { requireAdmin } from '../../../utils/auth.js'
export default defineEventHandler(async (event) => {
requireAdmin(event)
const id = Number(getRouterParam(event, 'id'))
const body = await readBody(event)
const db = useDB()
const updateData = { updatedAt: new Date().toISOString() }
if (body.title !== undefined) updateData.title = body.title
if (body.slug !== undefined) updateData.slug = body.slug
if (body.summary !== undefined) updateData.summary = body.summary
if (body.content !== undefined) updateData.content = body.content
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
if (body.published !== undefined) updateData.published = body.published ? 1 : 0
db.update(schema.articles)
.set(updateData)
.where(eq(schema.articles.id, id))
.run()
return { success: true }
})