/** * Detail - 藏品详情页面 * Version: 1.2.90x * 更新: */ import React, { useState, useEffect } from 'react' export default function Detail() { 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 [error, setError] = useState('') const [showDelete, setShowDelete] = useState(false) const [showImage, setShowImage] = useState(false) const [currentImageIndex, setCurrentImageIndex] = useState(0) useEffect(() => { if (id) { fetchDetail() } }, [id]) const fetchDetail = async () => { setLoading(true) const token = localStorage.getItem('token') try { const res = await fetch(`/api/collections/${id}`, { headers: token ? { 'Authorization': 'Bearer ' + token } : {} }) if (!res.ok) { const errorData = await res.json() const errorCode = errorData.error?.code || 'E00000' const errorMessage = errorData.error?.message || '加载失败' // 标准错误码处理 if (res.status === 404) { setError('E00033: 藏品不存在') } else if (res.status === 401) { setError('E00010: 未登录或登录已过期') } else if (res.status === 403) { setError('E00014: 无权访问此藏品') } else { setError(`${errorCode}: ${errorMessage}`) } setLoading(false) return } const data = await res.json() // 后端已返回 camelCase 格式,直接使用 const collectionData = data.data || data if (collectionData && collectionData.id) { setCollection(collectionData) } else { setError('E00000: 数据格式错误') } } catch (e) { console.error(e) setError('E00001: 网络连接失败') } setLoading(false) } const handleEdit = () => { window.location.hash = '#/edit?id=' + id } const goBack = () => { // 尝试返回到上次筛选的列表页面 const lastUrl = sessionStorage.getItem('lastListUrl') if (lastUrl) { sessionStorage.removeItem('lastListUrl') window.location.hash = '#' + lastUrl } else { window.location.hash = '#/list' } } 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 getStatusText = (status) => { const map = { 'in_collection': '收藏中', 'selling': '出售中', 'sold': '已售', 'grading': '送评中', 'repairing': '修复中', 'transit': '在途中', 'other': '其他' } return map[status] || status || '-' } const getCategoryText = (category) => { const map = { '自持': '自持', '寄存': '寄存', '寄售': '寄售', '共有': '共有', '寻号': '寻号', '其他': '其他' } return map[category] || category || '-' } const Field = ({ label, value, green }) => (
{label} {value || '-'}
) const Section = ({ title, children }) => (
{title}
{children}
) if (loading) { return
加载中...
} if (error) { return (
{error}
) } if (!collection) { return (
藏品不存在
) } return (
{/* 顶部 */}
藏品详情
{/* 主信息 */}
{/* 图片显示 */} {collection.images && collection.images.length > 0 && (
{collection.images.map((img, index) => (
{img.originalName { setCurrentImageIndex(index); setShowImage(true); }} style={{ width: '100%', aspectRatio: '1.5', objectFit: 'contain', borderRadius: '12px', border: '2px solid #10b981', cursor: 'pointer', boxShadow: '0 4px 12px rgba(0,0,0,0.3)', background: '#0f172a' }} onError={(e) => { // 图片加载失败时显示灰色占位符,不显示 logo e.target.style.display = 'none'; e.target.parentElement.innerHTML = '
无图片
'; }} /> {collection.images.length > 1 && (
{index + 1}/{collection.images.length}
)}
))}
)}
{collection.name}
{collection.prefixSerial || '-'}
{/* 信息区块 */}
{collection.remark && (
{collection.remark}
)}
{/* 删除确认弹窗 */} {showDelete && (
确定删除此藏品?
)} {/* 图片查看器 */} {showImage && collection.images && collection.images.length > 0 && (
setShowImage(false)} > {/* 左侧切换按钮 */} {collection.images.length > 1 && ( )} {/* 图片 */} {collection.images[currentImageIndex].originalName e.stopPropagation()} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} /> {/* 右侧切换按钮 */} {collection.images.length > 1 && ( )} {/* 图片指示器 */} {collection.images.length > 1 && (
e.stopPropagation()} > {collection.images.map((_, index) => (
setCurrentImageIndex(index)} style={{ width: '12px', height: '12px', borderRadius: '50%', background: index === currentImageIndex ? '#fbbf24' : 'rgba(255,255,255,0.3)', cursor: 'pointer', border: '2px solid #fff' }} /> ))}
)} {/* 关闭提示 */}
setShowImage(false)} > ×
)}
) } // v2.7.1