269 lines
8.1 KiB
TypeScript
269 lines
8.1 KiB
TypeScript
'use client'
|
||
|
||
import React, { useState } from 'react'
|
||
import { Button } from '@payloadcms/ui'
|
||
|
||
/**
|
||
* 管理员控制面板
|
||
* 用于执行管理操作:清理数据、系统维护等
|
||
*/
|
||
export default function AdminPanel() {
|
||
const [clearLoading, setClearLoading] = useState(false)
|
||
const [clearMessage, setClearMessage] = useState('')
|
||
const [showClearConfirm, setShowClearConfirm] = useState(false)
|
||
|
||
const [fixLoading, setFixLoading] = useState(false)
|
||
const [fixMessage, setFixMessage] = useState('')
|
||
|
||
const handleClearData = () => {
|
||
setShowClearConfirm(true)
|
||
setClearMessage('')
|
||
}
|
||
|
||
const handleConfirmClear = async () => {
|
||
setClearLoading(true)
|
||
setClearMessage('')
|
||
setShowClearConfirm(false)
|
||
|
||
try {
|
||
const response = await fetch('/api/clear-data?confirm=true', {
|
||
method: 'GET',
|
||
})
|
||
|
||
const data = await response.json()
|
||
|
||
if (data.success) {
|
||
setClearMessage(data.message || '数据清理成功!')
|
||
} else {
|
||
setClearMessage(`清理失败: ${data.error}`)
|
||
}
|
||
} catch (error) {
|
||
setClearMessage(`清理出错: ${error instanceof Error ? error.message : '未知错误'}`)
|
||
} finally {
|
||
setClearLoading(false)
|
||
}
|
||
}
|
||
|
||
const handleCancelClear = () => {
|
||
setShowClearConfirm(false)
|
||
setClearMessage('')
|
||
}
|
||
|
||
const handleFixDatabase = async () => {
|
||
if (!confirm('确定要修复数据库字段类型吗?这会修改 products 表的 thumbnail 字段。')) {
|
||
return
|
||
}
|
||
|
||
setFixLoading(true)
|
||
setFixMessage('')
|
||
|
||
try {
|
||
const response = await fetch('/api/fix-database', {
|
||
method: 'GET',
|
||
})
|
||
|
||
const data = await response.json()
|
||
|
||
if (data.success) {
|
||
setFixMessage(data.message || '数据库修复成功!')
|
||
} else {
|
||
setFixMessage(`修复失败: ${data.error}`)
|
||
}
|
||
} catch (error) {
|
||
setFixMessage(`修复出错: ${error instanceof Error ? error.message : '未知错误'}`)
|
||
} finally {
|
||
setFixLoading(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div style={{ padding: '2rem', maxWidth: '1200px', margin: '0 auto' }}>
|
||
<h1 style={{ marginBottom: '2rem', fontSize: '2rem', fontWeight: 'bold' }}>
|
||
🛠️ 管理员控制面板
|
||
</h1>
|
||
|
||
{/* 数据管理区域 */}
|
||
<div
|
||
style={{
|
||
backgroundColor: 'var(--theme-elevation-50)',
|
||
borderRadius: '8px',
|
||
padding: '1.5rem',
|
||
marginBottom: '1.5rem',
|
||
border: '1px solid var(--theme-elevation-100)',
|
||
}}
|
||
>
|
||
<h2 style={{ marginBottom: '1rem', fontSize: '1.25rem', fontWeight: '600' }}>
|
||
📦 数据管理
|
||
</h2>
|
||
|
||
<div
|
||
style={{
|
||
backgroundColor: 'var(--theme-elevation-0)',
|
||
borderRadius: '6px',
|
||
padding: '1.5rem',
|
||
border: '1px solid var(--theme-elevation-150)',
|
||
}}
|
||
>
|
||
<h3 style={{ marginBottom: '0.5rem', fontSize: '1rem', fontWeight: '600' }}>
|
||
🗑️ 清理数据库
|
||
</h3>
|
||
<p
|
||
style={{
|
||
marginBottom: '1rem',
|
||
fontSize: '0.875rem',
|
||
color: 'var(--theme-elevation-600)',
|
||
}}
|
||
>
|
||
清除所有商品、公告、文章数据(保留用户和媒体文件)
|
||
</p>
|
||
|
||
{showClearConfirm ? (
|
||
<div>
|
||
<div
|
||
style={{
|
||
marginBottom: '1rem',
|
||
padding: '1rem',
|
||
backgroundColor: 'var(--theme-error-50)',
|
||
borderRadius: '6px',
|
||
border: '1px solid var(--theme-error-500)',
|
||
}}
|
||
>
|
||
<p
|
||
style={{
|
||
margin: '0 0 0.5rem 0',
|
||
fontWeight: 'bold',
|
||
color: 'var(--theme-error-700)',
|
||
}}
|
||
>
|
||
⚠️ 确认清理所有数据?
|
||
</p>
|
||
<p style={{ margin: '0', fontSize: '0.875rem', color: 'var(--theme-error-600)' }}>
|
||
此操作不可撤销!将删除所有商品、公告和文章。
|
||
</p>
|
||
</div>
|
||
|
||
<div style={{ display: 'flex', gap: '0.75rem' }}>
|
||
<Button onClick={handleConfirmClear} disabled={clearLoading} buttonStyle="error">
|
||
{clearLoading ? '清理中...' : '确认清理'}
|
||
</Button>
|
||
<Button onClick={handleCancelClear} disabled={clearLoading} buttonStyle="secondary">
|
||
取消
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<Button onClick={handleClearData} disabled={clearLoading} buttonStyle="error">
|
||
清理数据库
|
||
</Button>
|
||
)}
|
||
|
||
{clearMessage && (
|
||
<div
|
||
style={{
|
||
marginTop: '1rem',
|
||
padding: '1rem',
|
||
backgroundColor:
|
||
clearMessage.includes('失败') || clearMessage.includes('出错')
|
||
? 'var(--theme-error-50)'
|
||
: 'var(--theme-success-50)',
|
||
borderRadius: '6px',
|
||
fontSize: '0.875rem',
|
||
border: `1px solid ${
|
||
clearMessage.includes('失败') || clearMessage.includes('出错')
|
||
? 'var(--theme-error-500)'
|
||
: 'var(--theme-success-500)'
|
||
}`,
|
||
}}
|
||
>
|
||
{clearMessage}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* 修复数据库区域 */}
|
||
<div
|
||
style={{
|
||
backgroundColor: 'var(--theme-elevation-0)',
|
||
borderRadius: '6px',
|
||
padding: '1.5rem',
|
||
marginTop: '1rem',
|
||
border: '1px solid var(--theme-elevation-150)',
|
||
}}
|
||
>
|
||
<h3 style={{ marginBottom: '0.5rem', fontSize: '1rem', fontWeight: '600' }}>
|
||
🔧 修复数据库
|
||
</h3>
|
||
<p
|
||
style={{
|
||
marginBottom: '1rem',
|
||
fontSize: '0.875rem',
|
||
color: 'var(--theme-elevation-600)',
|
||
}}
|
||
>
|
||
修复数据库字段类型(将 products.thumbnail 从 integer 改为 varchar)
|
||
</p>
|
||
|
||
<Button onClick={handleFixDatabase} disabled={fixLoading} buttonStyle="primary">
|
||
{fixLoading ? '修复中...' : '修复字段类型'}
|
||
</Button>
|
||
|
||
{fixMessage && (
|
||
<div
|
||
style={{
|
||
marginTop: '1rem',
|
||
padding: '1rem',
|
||
backgroundColor:
|
||
fixMessage.includes('失败') || fixMessage.includes('出错')
|
||
? 'var(--theme-error-50)'
|
||
: 'var(--theme-success-50)',
|
||
borderRadius: '6px',
|
||
fontSize: '0.875rem',
|
||
border: `1px solid ${
|
||
fixMessage.includes('失败') || fixMessage.includes('出错')
|
||
? 'var(--theme-error-500)'
|
||
: 'var(--theme-success-500)'
|
||
}`,
|
||
}}
|
||
>
|
||
{fixMessage}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 系统信息区域 */}
|
||
<div
|
||
style={{
|
||
backgroundColor: 'var(--theme-elevation-50)',
|
||
borderRadius: '8px',
|
||
padding: '1.5rem',
|
||
border: '1px solid var(--theme-elevation-100)',
|
||
}}
|
||
>
|
||
<h2 style={{ marginBottom: '1rem', fontSize: '1.25rem', fontWeight: '600' }}>
|
||
ℹ️ 系统信息
|
||
</h2>
|
||
|
||
<div
|
||
style={{
|
||
backgroundColor: 'var(--theme-elevation-0)',
|
||
borderRadius: '6px',
|
||
padding: '1rem',
|
||
border: '1px solid var(--theme-elevation-150)',
|
||
}}
|
||
>
|
||
<div style={{ marginBottom: '0.5rem' }}>
|
||
<strong>Payload CMS:</strong> v3.75.0
|
||
</div>
|
||
<div style={{ marginBottom: '0.5rem' }}>
|
||
<strong>数据库:</strong> PostgreSQL
|
||
</div>
|
||
<div style={{ marginBottom: '0.5rem' }}>
|
||
<strong>存储:</strong> Cloudflare R2 (S3 API)
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|