feat: 信息发布管理功能完善,界面优化

This commit is contained in:
甲辰生产 2026-03-26 20:26:51 +08:00
parent 66c086e35d
commit bc23e95691
1 changed files with 172 additions and 276 deletions

View File

@ -1,25 +1,20 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
// - /
export default function Info() { export default function Info() {
const [activeTab, setActiveTab] = useState('publish') const [activeTab, setActiveTab] = useState('publish')
const [showPublish, setShowPublish] = useState(false) const [showPublish, setShowPublish] = useState(false)
const [myList, setMyList] = useState([]) const [myList, setMyList] = useState([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [editingItem, setEditingItem] = useState(null)
//
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
edition: '龙钞', edition: '龙钞', type: '标百', isGraded: true, category: '成交', source: '直播', title: '', content: ''
type: '标百',
isGraded: true,
category: '成交',
source: '直播',
prices: {},
title: '',
content: ''
}) })
// useEffect(() => {
if (activeTab === 'manage') fetchMyList()
}, [activeTab])
useEffect(() => { useEffect(() => {
const now = new Date() const now = new Date()
const date = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}` const date = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`
@ -30,121 +25,66 @@ export default function Info() {
const API_BASE = localStorage.getItem('API_BASE') || '' const API_BASE = localStorage.getItem('API_BASE') || ''
//
useEffect(() => {
if (activeTab === 'manage') {
fetchMyList()
}
}, [activeTab])
const fetchMyList = async () => { const fetchMyList = async () => {
setLoading(true) setLoading(true)
try { try {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
const res = await fetch(`${API_BASE}/api/information/my`, { const res = await fetch(`${API_BASE}/api/information/my/list`, { headers: { Authorization: `Bearer ${token}` } })
headers: { Authorization: `Bearer ${token}` } setMyList(res.ok ? await res.json() : [])
}) } catch (e) { console.error(e) }
const data = await res.json()
setMyList(data || [])
} catch (e) {
console.error(e)
}
setLoading(false) setLoading(false)
} }
//
const handlePublish = async () => { const handlePublish = async () => {
if (!formData.title) { if (!formData.title) { alert('请填写标题'); return }
alert('请填写标题')
return
}
try { try {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
const gradeNote = formData.isGraded ? '(评级币)' : '(裸钞)' const res = await fetch(`${API_BASE}/api/information/`, {
method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
let priceContent = '' body: JSON.stringify({ title: formData.title, content: formData.content, info_type: formData.category === '成交' ? 'deal' : 'seek' })
if (formData.prices && Object.keys(formData.prices).length > 0) {
priceContent = '\n价格'
const priceLabels = {
price_4: '带4',
price_no4: '无4',
price_no47: '无47',
price_no347: '无347',
price_no1347: '无1347',
price_no247: '无247',
price_no1247: '无1247',
price_no12347: '无12347'
}
Object.entries(formData.prices).forEach(([key, value]) => {
if (value) {
priceContent += `${priceLabels[key] || key}${value} `
}
})
}
const res = await fetch(`${API_BASE}/api/information/publish`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: formData.title,
content: formData.content + priceContent,
info_type: formData.category === '成交' ? 'deal' : 'seek'
})
}) })
const data = await res.json() const data = await res.json()
if (data.id || data.code === 0) { if (data.id || data.code === 0) {
alert('发布成功!') alert('发布成功!')
setShowPublish(false) setShowPublish(false)
setFormData({ setFormData({ edition: '龙钞', type: '标百', isGraded: true, category: '成交', source: '直播', title: '', content: '' })
edition: '龙钞',
type: '标百',
isGraded: true,
category: '成交',
source: '直播',
prices: {},
title: '',
content: ''
})
fetchMyList() fetchMyList()
} else { } else { alert(data.message || '发布失败') }
alert(data.message || '发布失败') } catch (e) { alert('发布失败: ' + e.message) }
}
} catch (e) {
alert('发布失败: ' + e.message)
}
} }
// Tab const handleDelete = async (id) => {
const tabs = [ if (!confirm('确定删除这条信息吗?')) return
{ key: 'publish', label: '📝 发布行情' }, try {
{ key: 'manage', label: '📋 发布管理' } const token = localStorage.getItem('token')
] const res = await fetch(`${API_BASE}/api/information/${id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } })
if (res.ok) { alert('删除成功'); fetchMyList() } else { alert('删除失败') }
} catch (e) { alert('删除失败: ' + e.message) }
}
// const handleEdit = (item) => setEditingItem({ id: item.id, title: item.title, content: item.content })
const ButtonGroup = ({ options, value, onChange, label }) => (
<div style={{ marginBottom: '14px' }}> const handleSaveEdit = async () => {
{label && <label style={{ color: '#94a3b8', fontSize: '12px', display: 'block', marginBottom: '6px' }}>{label}</label>} if (!editingItem) return
<div style={{ display: 'flex', gap: '8px' }}> try {
const token = localStorage.getItem('token')
const res = await fetch(`${API_BASE}/api/information/${editingItem.id}`, {
method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ title: editingItem.title, content: editingItem.content })
})
if (res.ok) { alert('保存成功'); setEditingItem(null); fetchMyList() } else { alert('保存失败') }
} catch (e) { alert('保存失败: ' + e.message) }
}
const BtnGroup = ({ options, value, onChange, label }) => (
<div style={{ marginBottom: '16px' }}>
<div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '8px', fontWeight: '500' }}>{label}</div>
<div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
{options.map(opt => ( {options.map(opt => (
<button <button key={opt.value} onClick={() => onChange(opt.value)}
key={opt.value} style={{ padding: '10px 16px', borderRadius: '8px', border: value === opt.value ? '2px solid #10b981' : '1px solid #374151',
onClick={() => onChange(opt.value)} background: value === opt.value ? 'rgba(16,185,129,0.15)' : '#1f2937', color: value === opt.value ? '#10b981' : '#d1d5db',
style={{ cursor: 'pointer', fontSize: '13px', fontWeight: '500', transition: 'all 0.2s' }}>
flex: 1,
padding: '10px',
borderRadius: '6px',
border: value === opt.value ? '2px solid #fbbf24' : '1px solid #334155',
background: value === opt.value ? 'rgba(251,191,36,0.2)' : '#0f172a',
color: '#fff',
cursor: 'pointer',
fontSize: '14px'
}}
>
{opt.label} {opt.label}
</button> </button>
))} ))}
@ -152,199 +92,155 @@ export default function Info() {
</div> </div>
) )
// const Card = ({ children, title, action }) => (
const PriceGrid = () => { <div style={{ background: 'linear-gradient(145deg, #1f2937 0%, #111827 100%)', borderRadius: '16px', padding: '20px', marginBottom: '16px', border: '1px solid #374151', boxShadow: '0 4px 20px rgba(0,0,0,0.3)' }}>
const priceItems = [ {title && <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
{ key: 'price_4', label: '带4' }, <h3 style={{ color: '#f9fafb', margin: 0, fontSize: '16px', fontWeight: '600' }}>{title}</h3>
{ key: 'price_no4', label: '无4' }, {action}
{ key: 'price_no47', label: '无47' }, </div>}
{ key: 'price_no347', label: '无347' }, {children}
{ key: 'price_no1347', label: '无1347' }, </div>
{ key: 'price_no247', label: '无247' }, )
{ key: 'price_no1247', label: '无1247' },
{ key: 'price_no12347', label: '无12347' }
]
return ( const formatDate = (d) => d ? new Date(d).toLocaleString('zh-CN').slice(0, 16) : '-'
<div style={{ marginBottom: '14px' }}>
<label style={{ color: '#94a3b8', fontSize: '12px', display: 'block', marginBottom: '6px' }}>价格可选</label> return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '8px' }}> <div style={{ minHeight: '100vh', background: 'linear-gradient(180deg, #0f172a 0%, #1e293b 100%)', paddingBottom: '80px' }}>
{priceItems.map(item => ( {/* 顶部标签 */}
<div key={item.key}> <div style={{ position: 'sticky', top: 0, background: 'rgba(15,23,42,0.95)', backdropFilter: 'blur(10px)', padding: '16px 20px', borderBottom: '1px solid #1e293b', zIndex: 100 }}>
<label style={{ color: '#64748b', fontSize: '11px' }}>{item.label}</label> <div style={{ display: 'flex', gap: '8px', background: '#1e293b', borderRadius: '12px', padding: '4px' }}>
<input {[{ key: 'publish', label: '📝 发布行情', icon: '📝' }, { key: 'manage', label: '📋 发布管理', icon: '📋' }].map(t => (
type="number" <div key={t.key} onClick={() => setActiveTab(t.key)}
value={formData.prices?.[item.key] || ''} style={{ flex: 1, padding: '12px 16px', borderRadius: '10px', background: activeTab === t.key ? 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)' : 'transparent',
onChange={(e) => setFormData({ color: activeTab === t.key ? '#fff' : '#9ca3af', cursor: 'pointer', textAlign: 'center', fontSize: '14px', fontWeight: '600', transition: 'all 0.3s', boxShadow: activeTab === t.key ? '0 2px 10px rgba(59,130,246,0.4)' : 'none' }}>
...formData, {t.label}
prices: {...formData.prices, [item.key]: e.target.value}
})}
placeholder="¥"
style={{
width: '100%',
padding: '8px',
background: '#0f172a',
border: '1px solid #334155',
borderRadius: '4px',
color: '#fff',
boxSizing: 'border-box',
fontSize: '13px'
}}
/>
</div> </div>
))} ))}
</div> </div>
</div> </div>
)
}
const formatDate = (dateStr) => { <div style={{ padding: '20px' }}>
if (!dateStr) return '-' {activeTab === 'publish' && (
const date = new Date(dateStr) <div>
return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}` {/* 新增按钮 */}
} <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '20px' }}>
<button onClick={() => setShowPublish(!showPublish)}
style={{ background: showPublish ? 'linear-gradient(135deg, #6b7280 0%, #4b5563 100%)' : 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
color: '#fff', border: 'none', padding: '12px 24px', borderRadius: '10px', cursor: 'pointer', fontSize: '14px', fontWeight: '600', boxShadow: '0 4px 15px rgba(16,185,129,0.3)', transition: 'all 0.3s' }}>
{showPublish ? '✕ 收起表单' : '+ 新增发布'}
</button>
</div>
return ( {showPublish && (
<div style={{ minHeight: '100vh', background: '#0f172a', paddingBottom: '60px' }}> <Card title="📝 发布行情信息">
{/* Tab导航 */} <BtnGroup label="版别" options={[
<div style={{ display: 'flex', padding: '12px 16px', background: '#1e293b', gap: '8px', overflowX: 'auto' }}> { value: '龙钞', label: '🐉 龙钞' }, { value: '马钞', label: '🐎 马钞' }, { value: '蛇钞', label: '🐍 蛇钞' }, { value: '其他', label: '📄 其他' }
{tabs.map(tab => ( ]} value={formData.edition} onChange={v => setFormData({...formData, edition: v})} />
<div
key={tab.key}
onClick={() => setActiveTab(tab.key)}
style={{
padding: '10px 20px',
borderRadius: '8px',
background: activeTab === tab.key ? '#3b82f6' : 'transparent',
color: '#fff',
cursor: 'pointer',
whiteSpace: 'nowrap',
fontSize: '14px'
}}
>
{tab.label}
</div>
))}
</div>
{/* 发布行情 */} <div style={{ display: 'flex', gap: '12px', marginBottom: '16px' }}>
{activeTab === 'publish' && (
<div style={{ padding: '16px' }}>
<div style={{ marginBottom: '16px', textAlign: 'right' }}>
<button
onClick={() => setShowPublish(!showPublish)}
style={{
background: '#3b82f6',
color: '#fff',
border: 'none',
padding: '10px 20px',
borderRadius: '8px',
cursor: 'pointer',
fontSize: '14px'
}}
>
{showPublish ? '❌ 取消' : ' 新增发布'}
</button>
</div>
{showPublish && (
<div style={{ background: '#1e293b', borderRadius: '12px', padding: '16px', marginBottom: '16px' }}>
<h3 style={{ color: '#fbbf24', marginTop: 0, marginBottom: '16px' }}>📝 发布行情信息</h3>
<ButtonGroup label="版别 *" options={[
{ value: '龙钞', label: '🐉 龙钞' },
{ value: '马钞', label: '🐎 马钞' },
{ value: '蛇钞', label: '🐍 蛇钞' },
{ value: '其他', label: '📄 其他' }
]} value={formData.edition} onChange={(v) => setFormData({...formData, edition: v})} />
<div style={{ marginBottom: '14px' }}>
<div style={{ display: 'flex', gap: '12px' }}>
<div style={{ flex: 2 }}> <div style={{ flex: 2 }}>
<label style={{ color: '#94a3b8', fontSize: '12px' }}>类型 *</label> <div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '8px', fontWeight: '500' }}>类型</div>
<div style={{ display: 'flex', gap: '6px', marginTop: '6px' }}> <div style={{ display: 'flex', gap: '6px' }}>
{['标百', '标十', '单张'].map(t => ( {['标百', '标十', '单张'].map(t => (
<button key={t} onClick={() => setFormData({...formData, type: t})} <button key={t} onClick={() => setFormData({...formData, type: t})}
style={{ flex: 1, padding: '10px', borderRadius: '6px', style={{ flex: 1, padding: '10px', borderRadius: '8px', border: formData.type === t ? '2px solid #10b981' : '1px solid #374151',
border: formData.type === t ? '2px solid #fbbf24' : '1px solid #334155', background: formData.type === t ? 'rgba(16,185,129,0.15)' : '#1f2937', color: formData.type === t ? '#10b981' : '#d1d5db', cursor: 'pointer', fontSize: '13px' }}>{t}</button>
background: formData.type === t ? 'rgba(251,191,36,0.2)' : '#0f172a',
color: '#fff', cursor: 'pointer', fontSize: '13px' }}>
{t}
</button>
))} ))}
</div> </div>
</div> </div>
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<label style={{ color: '#94a3b8', fontSize: '12px' }}>是否评级</label> <div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '8px', fontWeight: '500' }}>是否评级</div>
<button onClick={() => setFormData({...formData, isGraded: !formData.isGraded})} <button onClick={() => setFormData({...formData, isGraded: !formData.isGraded})}
style={{ width: '100%', padding: '10px', marginTop: '6px', borderRadius: '6px', style={{ width: '100%', padding: '10px', borderRadius: '8px', border: formData.isGraded ? '2px solid #10b981' : '1px solid #374151',
border: formData.isGraded ? '2px solid #fbbf24' : '1px solid #334155', background: formData.isGraded ? 'rgba(16,185,129,0.15)' : '#1f2937', color: formData.isGraded ? '#10b981' : '#d1d5db', cursor: 'pointer', fontSize: '13px' }}>
background: formData.isGraded ? 'rgba(251,191,36,0.2)' : '#0f172a', {formData.isGraded ? '✓ 评级币' : '○ 裸钞'}
color: formData.isGraded ? '#fbbf24' : '#94a3b8', cursor: 'pointer', fontSize: '13px' }}>
{formData.isGraded ? '✅ 评级' : '○ 未评级'}
</button> </button>
</div> </div>
</div> </div>
</div>
<ButtonGroup label="分类 *" options={[ <BtnGroup label="分类" options={[
{ value: '成交', label: '💰 成交' }, { value: '成交', label: '💰 成交' }, { value: '求购', label: '🔍 求购' }, { value: '出售', label: '💵 出售' }
{ value: '求购', label: '🔍 求购' }, ]} value={formData.category} onChange={v => setFormData({...formData, category: v})} />
{ value: '出售', label: '💵 出售' }
]} value={formData.category} onChange={(v) => setFormData({...formData, category: v})} />
<ButtonGroup label="信息源 *" options={[ <BtnGroup label="信息来源" options={[
{ value: '直播', label: '📺 直播' }, { value: '直播', label: '📺 直播' }, { value: '一尘', label: '💼 一尘' }, { value: '爱藏', label: '📦 爱藏' }, { value: '其他', label: '📋 其他' }
{ value: '一尘', label: '💼 一尘' }, ]} value={formData.source} onChange={v => setFormData({...formData, source: v})} />
{ value: '爱藏', label: '📦 爱藏' },
{ value: '其他', label: '📋 其他' }
]} value={formData.source} onChange={(v) => setFormData({...formData, source: v})} />
<PriceGrid /> <div style={{ marginBottom: '16px' }}>
<div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '8px', fontWeight: '500' }}>标题自动生成</div>
<div style={{ marginBottom: '14px' }}> <input type="text" value={formData.title} readOnly
<label style={{ color: '#94a3b8', fontSize: '12px' }}>标题自动生成</label> style={{ width: '100%', padding: '14px', background: '#0f172a', border: '1px solid #374151', borderRadius: '10px', color: '#10b981', fontSize: '14px', boxSizing: 'border-box' }} />
<input type="text" value={formData.title} readOnly
style={{ width: '100%', padding: '10px', marginTop: '6px', background: '#0f172a',
border: '1px solid #334155', borderRadius: '6px', color: '#fbbf24', fontSize: '14px', boxSizing: 'border-box' }} />
</div>
<div style={{ marginBottom: '16px' }}>
<label style={{ color: '#94a3b8', fontSize: '12px' }}>正文</label>
<textarea value={formData.content} onChange={(e) => setFormData({...formData, content: e.target.value})}
placeholder="请输入详细信息..." rows={4}
style={{ width: '100%', padding: '10px', marginTop: '6px', background: '#0f172a',
border: '1px solid #334155', borderRadius: '6px', color: '#fff', resize: 'vertical', boxSizing: 'border-box' }} />
</div>
<button onClick={handlePublish}
style={{ width: '100%', padding: '14px', background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
border: 'none', borderRadius: '8px', color: '#fff', fontSize: '16px', fontWeight: 'bold', cursor: 'pointer' }}>
📤 提交发布
</button>
</div>
)}
</div>
)}
{/* 发布管理 */}
{activeTab === 'manage' && (
<div style={{ padding: '16px' }}>
<h3 style={{ color: '#fff', marginBottom: '16px' }}>📋 我的发布</h3>
{loading ? (
<div style={{ color: '#94a3b8', textAlign: 'center', padding: '20px' }}>加载中...</div>
) : myList.length === 0 ? (
<div style={{ color: '#94a3b8', textAlign: 'center', padding: '20px' }}>暂无发布记录</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
{myList.map(item => (
<div key={item.id} style={{ background: '#1e293b', borderRadius: '8px', padding: '12px' }}>
<div style={{ color: '#fbbf24', fontSize: '14px', marginBottom: '4px' }}>{item.title}</div>
<div style={{ color: '#94a3b8', fontSize: '12px' }}>{formatDate(item.created_at)} | {item.info_type === 'deal' ? '💰 成交' : '🔍 求购'}</div>
</div> </div>
))}
<div style={{ marginBottom: '20px' }}>
<div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '8px', fontWeight: '500' }}>正文内容</div>
<textarea value={formData.content} onChange={(e) => setFormData({...formData, content: e.target.value})} placeholder="请输入详细信息..." rows={4}
style={{ width: '100%', padding: '14px', background: '#0f172a', border: '1px solid #374151', borderRadius: '10px', color: '#fff', resize: 'vertical', boxSizing: 'border-box', fontSize: '14px' }} />
</div>
<button onClick={handlePublish}
style={{ width: '100%', padding: '16px', background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)', border: 'none', borderRadius: '12px', color: '#fff', fontSize: '16px', fontWeight: 'bold', cursor: 'pointer', boxShadow: '0 4px 15px rgba(245,158,11,0.3)', transition: 'transform 0.2s' }}>
🚀 提交发布
</button>
</Card>
)}
</div>
)}
{activeTab === 'manage' && (
<div>
<Card title="📋 我的发布">
{loading ? (
<div style={{ color: '#9ca3af', textAlign: 'center', padding: '30px' }}> 加载中...</div>
) : myList.length === 0 ? (
<div style={{ color: '#9ca3af', textAlign: 'center', padding: '30px', fontSize: '14px' }}>暂无发布记录</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
{myList.map(item => (
<div key={item.id} style={{ background: '#0f172a', borderRadius: '12px', padding: '16px', border: '1px solid #374151' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '8px' }}>
<div style={{ color: '#10b981', fontSize: '15px', fontWeight: '600', flex: 1 }}>{item.title}</div>
<span style={{ background: item.info_type === 'deal' ? 'rgba(16,185,129,0.2)' : 'rgba(59,130,246,0.2)', color: item.info_type === 'deal' ? '#10b981' : '#3b82f6', padding: '4px 10px', borderRadius: '20px', fontSize: '12px' }}>
{item.info_type === 'deal' ? '💰 成交' : '🔍 求购'}
</span>
</div>
{item.content && <div style={{ color: '#9ca3af', fontSize: '13px', marginBottom: '12px', lineHeight: '1.5' }}>{item.content}</div>}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div style={{ color: '#6b7280', fontSize: '12px' }}>{formatDate(item.created_at)}</div>
<div style={{ display: 'flex', gap: '8px' }}>
<button onClick={() => handleEdit(item)} style={{ padding: '8px 16px', borderRadius: '8px', border: '1px solid #3b82f6', background: 'transparent', color: '#3b82f6', cursor: 'pointer', fontSize: '13px' }}> 编辑</button>
<button onClick={() => handleDelete(item.id)} style={{ padding: '8px 16px', borderRadius: '8px', border: '1px solid #ef4444', background: 'transparent', color: '#ef4444', cursor: 'pointer', fontSize: '13px' }}>🗑 删除</button>
</div>
</div>
</div>
))}
</div>
)}
</Card>
</div>
)}
</div>
{/* 编辑弹窗 */}
{editingItem && (
<div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.8)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: '20px', backdropFilter: 'blur(5px)' }}>
<div style={{ background: '#1f2937', borderRadius: '16px', padding: '24px', width: '100%', maxWidth: '420px', border: '1px solid #374151', boxShadow: '0 20px 40px rgba(0,0,0,0.5)' }}>
<h3 style={{ color: '#f9fafb', marginBottom: '20px', fontSize: '18px', fontWeight: '600' }}> 编辑信息</h3>
<div style={{ marginBottom: '16px' }}>
<label style={{ color: '#9ca3af', fontSize: '13px', display: 'block', marginBottom: '8px' }}>标题</label>
<input value={editingItem.title} onChange={(e) => setEditingItem({...editingItem, title: e.target.value})}
style={{ width: '100%', padding: '14px', background: '#0f172a', border: '1px solid #374151', borderRadius: '10px', color: '#fff', boxSizing: 'border-box', fontSize: '14px' }} />
</div> </div>
)} <div style={{ marginBottom: '20px' }}>
<label style={{ color: '#9ca3af', fontSize: '13px', display: 'block', marginBottom: '8px' }}>内容</label>
<textarea value={editingItem.content} onChange={(e) => setEditingItem({...editingItem, content: e.target.value})}
rows={5} style={{ width: '100%', padding: '14px', background: '#0f172a', border: '1px solid #374151', borderRadius: '10px', color: '#fff', boxSizing: 'border-box', fontSize: '14px', resize: 'vertical' }} />
</div>
<div style={{ display: 'flex', gap: '12px' }}>
<button onClick={handleSaveEdit} style={{ flex: 1, padding: '14px', background: 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)', border: 'none', borderRadius: '10px', color: '#fff', cursor: 'pointer', fontSize: '14px', fontWeight: '600' }}>💾 保存</button>
<button onClick={() => setEditingItem(null)} style={{ flex: 1, padding: '14px', border: '1px solid #374151', borderRadius: '10px', background: 'transparent', color: '#9ca3af', cursor: 'pointer', fontSize: '14px' }}>取消</button>
</div>
</div>
</div> </div>
)} )}
</div> </div>