feat: 初始化慧遇书院官网一期
This commit is contained in:
7
server/api/admin/site/index.get.ts
Normal file
7
server/api/admin/site/index.get.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { requireAdmin } from '../../../utils/auth'
|
||||
import { readSiteDocument } from '../../../utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requireAdmin(event)
|
||||
return readSiteDocument('draft')
|
||||
})
|
||||
19
server/api/admin/site/index.put.ts
Normal file
19
server/api/admin/site/index.put.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { requireAdmin } from '../../../utils/auth'
|
||||
import { writeAuditLog } from '../../../utils/audit'
|
||||
import { useDatabase } from '../../../utils/db'
|
||||
import { siteDocumentSchema } from '../../../utils/site-schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireAdmin(event)
|
||||
const parsed = siteDocumentSchema.safeParse(await readBody(event))
|
||||
if (!parsed.success) {
|
||||
throw createError({ statusCode: 422, statusMessage: '内容校验失败', data: { issues: parsed.error.issues } })
|
||||
}
|
||||
const document = parsed.data
|
||||
const timestamp = new Date().toISOString()
|
||||
const db = useDatabase()
|
||||
db.prepare('UPDATE site_documents SET draft_json = ?, updated_by = ?, updated_at = ? WHERE document_key = ?')
|
||||
.run(JSON.stringify(document), user.id, timestamp, 'website')
|
||||
writeAuditLog(event, { operatorId: user.id, action: 'save_draft', entityType: 'site_document', entityKey: 'website' })
|
||||
return { data: document, updatedAt: timestamp }
|
||||
})
|
||||
35
server/api/admin/site/publish.post.ts
Normal file
35
server/api/admin/site/publish.post.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { requireAdmin } from '../../../utils/auth'
|
||||
import { writeAuditLog } from '../../../utils/audit'
|
||||
import { useDatabase } from '../../../utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireAdmin(event)
|
||||
const db = useDatabase()
|
||||
const timestamp = new Date().toISOString()
|
||||
|
||||
const publish = db.transaction(() => {
|
||||
const row = db.prepare('SELECT draft_json FROM site_documents WHERE document_key = ?').get('website') as { draft_json: string }
|
||||
const versionRow = db.prepare(`
|
||||
SELECT COALESCE(MAX(version), 0) + 1 AS version FROM revisions
|
||||
WHERE entity_type = ? AND entity_key = ?
|
||||
`).get('site_document', 'website') as { version: number }
|
||||
db.prepare(`
|
||||
INSERT INTO revisions (entity_type, entity_key, version, snapshot_json, operator_id, action, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`).run('site_document', 'website', versionRow.version, row.draft_json, user.id, 'publish', timestamp)
|
||||
db.prepare(`
|
||||
UPDATE site_documents SET published_json = draft_json, updated_by = ?, updated_at = ?, published_at = ?
|
||||
WHERE document_key = ?
|
||||
`).run(user.id, timestamp, timestamp, 'website')
|
||||
db.prepare(`
|
||||
DELETE FROM revisions WHERE entity_type = ? AND entity_key = ? AND id NOT IN (
|
||||
SELECT id FROM revisions WHERE entity_type = ? AND entity_key = ? ORDER BY version DESC LIMIT 20
|
||||
)
|
||||
`).run('site_document', 'website', 'site_document', 'website')
|
||||
return versionRow.version
|
||||
})
|
||||
|
||||
const version = publish()
|
||||
writeAuditLog(event, { operatorId: user.id, action: 'publish', entityType: 'site_document', entityKey: 'website', metadata: { version } })
|
||||
return { success: true, publishedAt: timestamp, version }
|
||||
})
|
||||
11
server/api/admin/site/revisions.get.ts
Normal file
11
server/api/admin/site/revisions.get.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useDatabase } from '../../../utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requireAdmin(event)
|
||||
const rows = useDatabase().prepare(`
|
||||
SELECT version, action, comment, created_at AS createdAt
|
||||
FROM revisions WHERE entity_type = 'site_document' AND entity_key = 'website'
|
||||
ORDER BY version DESC LIMIT 20
|
||||
`).all() as Array<{ version: number; action: string; comment: string | null; createdAt: string }>
|
||||
return { data: rows }
|
||||
})
|
||||
16
server/api/admin/site/revisions/[version]/restore.post.ts
Normal file
16
server/api/admin/site/revisions/[version]/restore.post.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { useDatabase } from '../../../../../utils/db'
|
||||
import { siteDocumentSchema } from '../../../../../utils/site-schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireAdmin(event)
|
||||
const version = Number(getRouterParam(event, 'version'))
|
||||
if (!Number.isSafeInteger(version) || version < 1) throw createError({ statusCode: 400, statusMessage: '无效的版本号' })
|
||||
const db = useDatabase()
|
||||
const revision = db.prepare(`SELECT snapshot_json FROM revisions WHERE entity_type = 'site_document' AND entity_key = 'website' AND version = ?`).get(version) as { snapshot_json: string } | undefined
|
||||
if (!revision) throw createError({ statusCode: 404, statusMessage: '历史版本不存在' })
|
||||
const snapshot = siteDocumentSchema.parse(JSON.parse(revision.snapshot_json))
|
||||
const timestamp = new Date().toISOString()
|
||||
db.prepare('UPDATE site_documents SET draft_json = ?, updated_by = ?, updated_at = ? WHERE document_key = ?').run(JSON.stringify(snapshot), user.id, timestamp, 'website')
|
||||
writeAuditLog(event, { operatorId: user.id, action: 'revision.restore_to_draft', entityType: 'site_document', entityKey: 'website', metadata: { version } })
|
||||
return { data: snapshot, restoredVersion: version, updatedAt: timestamp }
|
||||
})
|
||||
Reference in New Issue
Block a user