576 lines
24 KiB
Plaintext
576 lines
24 KiB
Plaintext
import React, { useState, useEffect, useRef } from 'react'
|
||
|
||
|
||
// 通用 Input 组件
|
||
const Input = ({ form, handleChange, label, field, type = 'text', options = null }) => {
|
||
const onChange = (e) => {
|
||
const value = e.target.value
|
||
if (type === 'number' && value !== '') {
|
||
const num = parseFloat(value)
|
||
handleChange(field, isNaN(num) ? '' : num)
|
||
} else handleChange(field, value)
|
||
}
|
||
return (
|
||
<div style={{ flex: 1, minWidth: '45%', marginBottom: '12px' }}>
|
||
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>{label}</div>
|
||
{options ? (
|
||
<select value={form[field] || ''} onChange={onChange}
|
||
style={{ background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', color: '#fff', padding: '8px', borderRadius: '6px', width: '100%', fontSize: '13px' }}>
|
||
<option value="">请选择</option>
|
||
{options.map(o => <option key={o.value} value={o.value} style={{color:'#000'}}>{o.label}</option>)}
|
||
</select>
|
||
) : (
|
||
<input type={type} value={form[field] ?? ''} onChange={onChange}
|
||
style={{ background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', color: '#fff', padding: '8px', borderRadius: '6px', width: '100%', fontSize: '13px' }} />
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default function Edit() {
|
||
const params = new URLSearchParams(window.location.hash.split('?')[1] || '')
|
||
const id = params.get('id')
|
||
|
||
const [collection, setCollection] = useState(null)
|
||
const [loading, setLoading] = useState(true)
|
||
const [saving, setSaving] = useState(false)
|
||
const [form, setForm] = useState({})
|
||
const [showDelete, setShowDelete] = useState(false)
|
||
const [collectionImages, setCollectionImages] = useState([])
|
||
const fileInputRef = useRef(null)
|
||
const [editingImageIndex, setEditingImageIndex] = useState(-1)
|
||
|
||
useEffect(() => {
|
||
if (id) {
|
||
fetchDetail()
|
||
}
|
||
}, [id])
|
||
|
||
// 图片上传处理
|
||
const handleImageUpload = async (e) => {
|
||
const files = Array.from(e.target.files)
|
||
if (files.length === 0) return
|
||
|
||
const token = localStorage.getItem('token')
|
||
const maxImages = 3
|
||
|
||
// 检查是否超过限制
|
||
const currentCount = collection.images ? collection.images.length : 0
|
||
if (editingImageIndex === -1 && currentCount + files.length > maxImages) {
|
||
alert(`最多只能上传${maxImages}张图片`)
|
||
return
|
||
}
|
||
|
||
// 更换图片(点击已有图片)
|
||
if (editingImageIndex >= 0) {
|
||
const file = files[0]
|
||
const oldImage = collection.images[editingImageIndex]
|
||
|
||
const imgFormData = new FormData()
|
||
imgFormData.append('file', file)
|
||
|
||
try {
|
||
// 先上传新图片
|
||
const uploadRes = await fetch(`/api/collections/upload-image?collection_id=${id}`, {
|
||
method: 'POST',
|
||
headers: { 'Authorization': 'Bearer ' + token },
|
||
body: imgFormData
|
||
})
|
||
|
||
if (uploadRes.ok) {
|
||
// 删除旧图片
|
||
await fetch(`/api/collections/images/${oldImage.id}`, {
|
||
method: 'DELETE',
|
||
headers: { 'Authorization': 'Bearer ' + token }
|
||
})
|
||
|
||
// 重新加载详情
|
||
await fetchDetail()
|
||
alert('图片已更换')
|
||
}
|
||
} catch (err) {
|
||
console.error('图片更换失败:', err)
|
||
alert('更换失败,请重试')
|
||
}
|
||
|
||
setEditingImageIndex(-1)
|
||
return
|
||
}
|
||
|
||
// 添加新图片
|
||
for (const file of files) {
|
||
const imgFormData = new FormData()
|
||
imgFormData.append('file', file)
|
||
|
||
try {
|
||
const res = await fetch(`/api/collections/upload-image?collection_id=${id}`, {
|
||
method: 'POST',
|
||
headers: { 'Authorization': 'Bearer ' + token },
|
||
body: imgFormData
|
||
})
|
||
|
||
if (res.ok) {
|
||
// 重新加载藏品详情
|
||
await fetchDetail()
|
||
}
|
||
} catch (err) {
|
||
console.error('图片上传失败:', err)
|
||
}
|
||
}
|
||
}
|
||
|
||
const handleDeleteImage = async (imageId) => {
|
||
if (!confirm('确定删除这张图片吗?')) return
|
||
|
||
const token = localStorage.getItem('token')
|
||
|
||
try {
|
||
const res = await fetch(`/api/collections/images/${imageId}`, {
|
||
method: 'DELETE',
|
||
headers: { 'Authorization': 'Bearer ' + token }
|
||
})
|
||
|
||
if (res.ok) {
|
||
await fetchDetail()
|
||
}
|
||
} catch (err) {
|
||
console.error('图片删除失败:', err)
|
||
}
|
||
}
|
||
|
||
const fetchDetail = async () => {
|
||
setLoading(true)
|
||
const token = localStorage.getItem('token')
|
||
try {
|
||
const res = await fetch(`/api/collections/${id}`, {
|
||
headers: token ? { 'Authorization': 'Bearer ' + token } : {}
|
||
})
|
||
const data = await res.json()
|
||
const item = (data.code === 200 ? data.data : data)
|
||
if (item && item.id) {
|
||
setCollection(item)
|
||
// 设置特殊信息默认值
|
||
const yearMatch = item.version ? item.version.match(/(20\d{2})/) : null
|
||
const defaultForm = {
|
||
...item,
|
||
issuer: item.issuer || '中国人民银行',
|
||
issueYear: item.issueYear || (yearMatch ? yearMatch[1] : '2024'),
|
||
material: item.material || '塑料钞',
|
||
issueQuantity: item.issueQuantity || '1 亿'
|
||
}
|
||
setForm(defaultForm)
|
||
// 加载图片
|
||
if (item.images && Array.isArray(item.images)) {
|
||
setCollectionImages(item.images)
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.error('加载详情失败:', e)
|
||
}
|
||
setLoading(false)
|
||
}
|
||
|
||
const handleChange = (key, value) => {
|
||
setForm({ ...form, [key]: value })
|
||
// 填入出售价时自动把状态改为"已售"
|
||
if (key === 'targetPrice' && value) {
|
||
setForm(prev => ({ ...prev, status: 'sold' }))
|
||
}
|
||
// 版别变化时同步发行年份
|
||
if (key === 'version') {
|
||
const yearMatch = value.match(/(20\d{2})/)
|
||
if (yearMatch) {
|
||
setForm(prev => ({ ...prev, issueYear: yearMatch[1] }))
|
||
}
|
||
}
|
||
}
|
||
|
||
const handleSave = async () => {
|
||
setSaving(true)
|
||
setError('')
|
||
const token = localStorage.getItem('token')
|
||
|
||
// 1. 先检查是否重复(同版别、同冠字号)
|
||
if (form.prefixSerial) {
|
||
const checkRes = await fetch(`/api/collections?search=${encodeURIComponent(form.prefixSerial)}`, {
|
||
headers: { 'Authorization': 'Bearer ' + token }
|
||
})
|
||
const checkData = await checkRes.json()
|
||
const collections = checkData.data || checkData || []
|
||
const duplicate = collections.find(c =>
|
||
c.version === form.version &&
|
||
c.prefixSerial === form.prefixSerial &&
|
||
c.id !== id // 排除自己
|
||
)
|
||
if (duplicate) {
|
||
setError('已经录入过同版同号藏品!')
|
||
setSaving(false)
|
||
return
|
||
}
|
||
}
|
||
|
||
// 转换字段名:camelCase 转字段编码
|
||
const convertField = (obj) => {
|
||
const map = {
|
||
// f99 系统字段
|
||
id: 'f99_90_id',
|
||
userId: 'f99_91_user_id',
|
||
createdAt: 'f99_92_created_at',
|
||
updatedAt: 'f99_93_updated_at',
|
||
// f01 基本信息
|
||
name: 'f01_01_name',
|
||
code: 'f01_02_code',
|
||
category: 'f01_03_category',
|
||
status: 'f01_04_status',
|
||
remark: 'f01_05_remark',
|
||
// f02 详细字段
|
||
prefixSerial: 'f02_10_prefix_serial',
|
||
version: 'f02_11_version',
|
||
packaging: 'f02_12_packaging',
|
||
rarity: 'f02_13_rarity',
|
||
// f03 评级信息
|
||
isGraded: 'f03_20_is_graded',
|
||
gradingCompany: 'f03_21_grading_company',
|
||
gradingScore: 'f03_22_grading_score',
|
||
threeStar: 'f03_23_three_star',
|
||
// f04 特殊信息
|
||
specialMark: 'f04_30_special_mark',
|
||
serialFeature: 'f04_31_serial_feature',
|
||
issuer: 'f04_32_issuer',
|
||
issueYear: 'f04_33_issue_year',
|
||
material: 'f04_34_material',
|
||
denomination: 'f04_35_denomination',
|
||
issueQuantity: 'f04_36_issue_quantity',
|
||
// f05 价格信息
|
||
costPrice: 'f05_40_cost_price',
|
||
targetPrice: 'f05_41_target_price',
|
||
goalPrice: 'f05_42_goal_price',
|
||
repairFee: 'f05_43_repair_fee',
|
||
gradingFee: 'f05_44_grading_fee',
|
||
// f06 其他信息
|
||
purpose: 'f06_50_purpose'
|
||
}
|
||
const result = {}
|
||
// 数字字段列表
|
||
const numberFields = ['costPrice', 'targetPrice', 'goalPrice', 'repairFee', 'gradingFee']
|
||
for (const key in obj) {
|
||
let value = obj[key]
|
||
// 过滤空字符串为 null
|
||
if (value === '' || value === null) {
|
||
value = null
|
||
}
|
||
// 数字字段转换为浮点数
|
||
else if (numberFields.includes(key)) {
|
||
value = parseFloat(value)
|
||
if (isNaN(value)) value = null
|
||
}
|
||
result[map[key] || key] = value
|
||
}
|
||
return result
|
||
}
|
||
try {
|
||
const res = await fetch(`/api/collections/${id}`, {
|
||
method: 'PUT',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer ' + token
|
||
},
|
||
body: JSON.stringify(convertField(form))
|
||
})
|
||
if (res.ok) {
|
||
alert('保存成功!')
|
||
// 刷新首页统计数据
|
||
if (window.refreshHome) {
|
||
window.refreshHome()
|
||
}
|
||
window.location.hash = '#/detail?id=' + id
|
||
} else {
|
||
const data = await res.json()
|
||
alert('保存失败: ' + (data.error || '未知错误'))
|
||
}
|
||
} catch (e) {
|
||
alert('保存失败: ' + e.message)
|
||
}
|
||
setSaving(false)
|
||
}
|
||
|
||
const handleDelete = () => {
|
||
setShowDelete(true)
|
||
}
|
||
|
||
const doDelete = async () => {
|
||
const token = localStorage.getItem('token')
|
||
try {
|
||
const res = await fetch(`/api/collections/${id}`, {
|
||
method: 'DELETE',
|
||
headers: {
|
||
'Authorization': 'Bearer ' + token
|
||
}
|
||
})
|
||
if (res.ok) {
|
||
alert('删除成功!')
|
||
if (window.refreshList) window.refreshList()
|
||
window.location.hash = '#/list'
|
||
} else {
|
||
alert('删除失败')
|
||
}
|
||
} catch (e) {
|
||
alert('删除失败')
|
||
}
|
||
setShowDelete(false)
|
||
}
|
||
|
||
const goBack = () => {
|
||
window.location.hash = '#/detail?id=' + id
|
||
}
|
||
|
||
const statusOptions = [
|
||
{ value: 'in_collection', label: '收藏中' },
|
||
{ value: 'selling', label: '出售中' },
|
||
{ value: 'sold', label: '已售' },
|
||
{ value: 'grading', label: '送评中' },
|
||
{ value: 'repairing', label: '修复中' },
|
||
{ value: 'transit', label: '在途中' },
|
||
{ value: 'other', label: '其他' }
|
||
]
|
||
|
||
const categoryOptions = [
|
||
{ value: '自持', label: '自持' },
|
||
{ value: '寄存', label: '寄存' },
|
||
{ value: '寄售', label: '寄售' },
|
||
{ value: '共有', label: '共有' },
|
||
{ value: '寻号', label: '寻号' },
|
||
{ value: '其他', label: '其他' }
|
||
]
|
||
|
||
const rarityOptions = [
|
||
{ value: '通货', label: '通货' },
|
||
{ value: '特色', label: '特色' },
|
||
{ value: '少见', label: '少见' },
|
||
{ value: '稀有', label: '稀有' },
|
||
{ value: '珍品', label: '珍品' },
|
||
{ value: '孤品', label: '孤品' }
|
||
]
|
||
|
||
if (loading) {
|
||
return <div style={{ padding: '40px', textAlign: 'center', color: '#94a3b8' }}>加载中...</div>
|
||
}
|
||
|
||
return (
|
||
<div style={{ background: '#0f172a', minHeight: '100vh', overflowY: 'auto', paddingBottom: '120px' }}>
|
||
{/* 顶部 */}
|
||
<div style={{ padding: '16px', background: 'rgba(255,255,255,0.02)', borderBottom: '1px solid rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', position: 'sticky', top: 0, zIndex: 100 }}>
|
||
<button onClick={goBack} style={{ background: 'none', border: 'none', fontSize: '20px', cursor: 'pointer', padding: '8px', color: '#fff' }}>←</button>
|
||
<span style={{ fontSize: '18px', fontWeight: 'bold', marginLeft: '8px', color: '#fff' }}>编辑藏品</span>
|
||
</div>
|
||
|
||
<div style={{ padding: '16px' }}>
|
||
{/* 图片预览区域 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '12px' }}>
|
||
<div style={{ color: '#fbbf24', fontSize: '13px', fontWeight: 'bold' }}>藏品图片</div>
|
||
{collectionImages.length > 0 && (
|
||
<button
|
||
onClick={() => fileInputRef.current?.click()}
|
||
style={{
|
||
padding: '6px 12px',
|
||
background: 'rgba(34, 197, 94, 0.2)',
|
||
color: '#22c55e',
|
||
border: '1px solid #22c55e',
|
||
borderRadius: '6px',
|
||
fontSize: '12px',
|
||
cursor: 'pointer',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '4px'
|
||
}}
|
||
>
|
||
📷 更换图片
|
||
</button>
|
||
)}
|
||
</div>
|
||
|
||
<input
|
||
ref={fileInputRef}
|
||
type="file"
|
||
accept="image/*"
|
||
onChange={handleImageUpload}
|
||
style={{ display: 'none' }}
|
||
/>
|
||
|
||
{collectionImages.length > 0 ? (
|
||
<div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: '12px' }}>
|
||
{collectionImages.map((img, index) => (
|
||
<div key={img.id || index} style={{ position: 'relative' }}>
|
||
<img
|
||
src={`http://120.26.133.10:3000/${img.path || `uploads/collections/${img.filename}`}`}
|
||
alt={img.original_name || img.filename || '藏品图片'}
|
||
style={{
|
||
width: '100%',
|
||
aspectRatio: '1.5',
|
||
objectFit: 'contain',
|
||
borderRadius: '12px',
|
||
border: '2px solid #10b981',
|
||
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
|
||
background: 'rgba(0,0,0,0.3)'
|
||
}}
|
||
/>
|
||
<div style={{
|
||
position: 'absolute',
|
||
top: '8px',
|
||
left: '8px',
|
||
background: 'rgba(0,0,0,0.6)',
|
||
color: '#fff',
|
||
padding: '4px 8px',
|
||
borderRadius: '4px',
|
||
fontSize: '12px'
|
||
}}>{index + 1}/{collectionImages.length}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<div
|
||
onClick={() => fileInputRef.current?.click()}
|
||
style={{
|
||
aspectRatio: '1.5',
|
||
background: 'rgba(255,255,255,0.05)',
|
||
border: '2px dashed #fbbf24',
|
||
borderRadius: '12px',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
cursor: 'pointer',
|
||
color: '#fbbf24',
|
||
fontSize: '12px',
|
||
transition: 'all 0.2s'
|
||
}}
|
||
>
|
||
<div style={{ fontSize: '48px', marginBottom: '8px' }}>📷</div>
|
||
<div style={{ fontWeight: 'bold', marginBottom: '4px' }}>点击上传图片</div>
|
||
<div style={{ fontSize: '11px', color: '#94a3b8' }}>
|
||
最多可上传 1 张
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* 基本信息 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ color: '#fbbf24', fontSize: '13px', fontWeight: 'bold', marginBottom: '12px' }}>基本信息</div>
|
||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px' }}>
|
||
<Input form={form} handleChange={handleChange} label="名称 *" field="name" />
|
||
<Input form={form} handleChange={handleChange} label="持仓类型" field="category" options={categoryOptions} />
|
||
<Input form={form} handleChange={handleChange} label="珍惜度" field="rarity" options={rarityOptions} />
|
||
<Input form={form} handleChange={handleChange} label="冠字序号" field="prefixSerial" />
|
||
<Input form={form} handleChange={handleChange} label="版别" field="version" />
|
||
<Input form={form} handleChange={handleChange} label="面值" field="denomination" />
|
||
<Input form={form} handleChange={handleChange} label="状态" field="status" options={statusOptions} />
|
||
<Input form={form} handleChange={handleChange} label="包装" field="packaging" options={packagingOptions} />
|
||
</div>
|
||
<div style={{ marginTop: '12px', paddingTop: '12px', borderTop: '1px solid rgba(255,255,255,0.05)' }}>
|
||
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap' }}>
|
||
<div style={{ flex: 1, minWidth: '45%' }}>
|
||
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>编号</div>
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', color: '#fbbf24', padding: '8px', borderRadius: '6px', fontSize: '13px', fontFamily: 'monospace', fontWeight: 'bold' }}>
|
||
{form.code || '(保存后自动生成)'}
|
||
</div>
|
||
</div>
|
||
<div style={{ flex: 1, minWidth: '45%' }}>
|
||
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>创建时间</div>
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', color: '#94a3b8', padding: '8px', borderRadius: '6px', fontSize: '13px' }}>
|
||
{form.createdAt ? new Date(form.createdAt).toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\//g, '-') : '(保存后自动生成)'}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 评级信息 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ color: '#fbbf24', fontSize: '13px', fontWeight: 'bold', marginBottom: '12px' }}>评级信息</div>
|
||
<div style={{ marginBottom: '12px', display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||
<input
|
||
type="checkbox"
|
||
id="isGraded"
|
||
checked={form.isGraded || false}
|
||
onChange={(e) => handleChange('isGraded', e.target.checked)}
|
||
style={{ width: '22px', height: '22px', cursor: 'pointer', backgroundColor: form.isGraded ? '#22c55e' : 'rgba(255,255,255,0.1)', border: '2px solid #22c55e', borderRadius: '4px', appearance: 'none', WebkitAppearance: 'none' }}
|
||
/>
|
||
<label htmlFor="isGraded" style={{ color: '#fff', cursor: 'pointer', fontSize: '15px' }}>是否评级</label>
|
||
</div>
|
||
<Input form={form} handleChange={handleChange} label="评级公司" field="gradingCompany" />
|
||
<Input form={form} handleChange={handleChange} label="评级分数" field="gradingScore" />
|
||
<Input form={form} handleChange={handleChange} label="特殊标识" field="specialMark" />
|
||
<div style={{ marginBottom: '12px', display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||
<input
|
||
type="checkbox"
|
||
id="threeStar"
|
||
checked={form.threeStar || false}
|
||
onChange={(e) => handleChange('threeStar', e.target.checked)}
|
||
style={{ width: '22px', height: '22px', cursor: 'pointer', backgroundColor: form.threeStar ? '#22c55e' : 'rgba(255,255,255,0.1)', border: '2px solid #22c55e', borderRadius: '4px', appearance: 'none', WebkitAppearance: 'none' }}
|
||
/>
|
||
<label htmlFor="threeStar" style={{ color: '#fff', cursor: 'pointer', fontSize: '15px' }}>三星</label>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 特殊信息 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ color: '#fbbf24', fontSize: '13px', fontWeight: 'bold', marginBottom: '12px' }}>特殊信息</div>
|
||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px' }}>
|
||
<Input form={form} handleChange={handleChange} label="号码特征" field="serialFeature" />
|
||
<Input form={form} handleChange={handleChange} label="发行方" field="issuer" />
|
||
<Input form={form} handleChange={handleChange} label="发行年份" field="issueYear" />
|
||
<Input form={form} handleChange={handleChange} label="材质" field="material" />
|
||
<Input form={form} handleChange={handleChange} label="发行量" field="issueQuantity" />
|
||
</div>
|
||
</div>
|
||
|
||
{/* 价格信息 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ color: '#fbbf24', fontSize: '13px', fontWeight: 'bold', marginBottom: '12px' }}>价格信息</div>
|
||
<Input form={form} handleChange={handleChange} label="成本价" field="costPrice" type="number" />
|
||
<Input form={form} handleChange={handleChange} label="目标价" field="targetPrice" type="number" />
|
||
<Input form={form} handleChange={handleChange} label="出售价" field="goalPrice" type="number" />
|
||
<Input form={form} handleChange={handleChange} label="修复费" field="repairFee" type="number" />
|
||
<Input form={form} handleChange={handleChange} label="评级费" field="gradingFee" type="number" />
|
||
<Input form={form} handleChange={handleChange} label="用途" field="purpose" />
|
||
</div>
|
||
|
||
{/* 备注 */}
|
||
<div style={{ background: 'rgba(255,255,255,0.03)', borderRadius: '12px', padding: '16px', marginBottom: '12px' }}>
|
||
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>备注</div>
|
||
<textarea
|
||
value={form.remark || ''}
|
||
onChange={(e) => handleChange('remark', e.target.value)}
|
||
rows={3}
|
||
style={{ background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', color: '#fff', padding: '8px', borderRadius: '8px', width: '100%', resize: 'none' }}
|
||
/>
|
||
</div>
|
||
|
||
{/* 按钮 */}
|
||
<button onClick={saving ? null : handleSave} disabled={saving} style={{ width: '100%', padding: '14px', background: saving ? '#64748b' : '#fbbf24', color: '#1e293b', border: 'none', borderRadius: '10px', fontSize: '16px', fontWeight: '600', marginBottom: '12px', cursor: saving ? 'not-allowed' : 'pointer' }}>
|
||
{saving ? '保存中...' : '保存'}
|
||
</button>
|
||
|
||
<button onClick={handleDelete} style={{ width: '100%', padding: '14px', background: 'rgba(239,68,68,0.1)', color: '#ef4444', border: '1px solid #ef4444', borderRadius: '10px', fontSize: '16px', cursor: 'pointer' }}>
|
||
删除藏品
|
||
</button>
|
||
</div>
|
||
|
||
{/* 删除确认弹窗 */}
|
||
{showDelete && (
|
||
<div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.8)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 }}>
|
||
<div style={{ background: '#1e293b', borderRadius: '12px', padding: '24px', width: '80%', maxWidth: '300px' }}>
|
||
<div style={{ color: '#fff', fontSize: '16px', fontWeight: 'bold', marginBottom: '16px', textAlign: 'center' }}>确定删除此藏品?</div>
|
||
<div style={{ display: 'flex', gap: '12px' }}>
|
||
<button onClick={() => setShowDelete(false)} style={{ flex: 1, padding: '12px', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '8px', fontSize: '13px' }}>取消</button>
|
||
<button onClick={doDelete} style={{ flex: 1, padding: '12px', background: '#ef4444', color: '#fff', border: 'none', borderRadius: '8px', fontSize: '13px' }}>删除</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|