import React, { useState, useEffect } from 'react' import { APP_VERSION } from '../config/version' const API_BASE = localStorage.getItem('API_BASE') || '' export default function List() { const [collections, setCollections] = useState([]) const [loading, setLoading] = useState(true) const [filter, setFilter] = useState('') const [filterType, setFilterType] = useState('') const urlParams = new URLSearchParams(window.location.hash.split('?')[1] || '') const urlUserId = urlParams.get('userId') || '' const [userIdFilter, setUserIdFilter] = useState(urlUserId) const [sortField, setSortField] = useState('createdAt') const [sortOrder, setSortOrder] = useState('desc') const [viewMode, setViewMode] = useState('list') const [key, setKey] = useState(0) const [search, setSearch] = useState('') const [isAdmin, setIsAdmin] = useState(false) const [page, setPage] = useState(1) const [pagination, setPagination] = useState({ total: 0, pages: 1 }) const [activeTab, setActiveTab] = useState('collections') // collections-藏品, deals-行情 const [dealSearch, setDealSearch] = useState('') const [dealSortField, setDealSortField] = useState('created_at') const [dealSortOrder, setDealSortOrder] = useState('desc') const [myDeals, setMyDeals] = useState([]) const [dealsLoading, setDealsLoading] = useState(false) useEffect(() => { // 检查是否管理员 const userStr = localStorage.getItem('user') if (userStr) { try { const user = JSON.parse(userStr) setIsAdmin(user.role === 'admin') } catch (e) {} } // 监听hash变化,重新读取筛选参数 const handleHashChange = () => { const params = new URLSearchParams(window.location.hash.split('?')[1] || '') // 支持两种格式:filter=category&value=自持 或 filter=category=自持 let filterTypeParam = params.get('filter') || '' let valueParam = params.get('value') || '' if (filterTypeParam && valueParam) { // 新格式:filter=category&value=自持 setFilterType(filterTypeParam) setFilter(decodeURIComponent(valueParam)) } else if (filterTypeParam && filterTypeParam.includes('=')) { // 旧格式:filter=category=自持 const [type, value] = filterTypeParam.split('=') setFilterType(type) setFilter(decodeURIComponent(value)) } else { setFilter('') setFilterType('') } fetchCollections() } handleHashChange() window.addEventListener('hashchange', handleHashChange) window.addEventListener('focus', fetchCollections) return () => { window.removeEventListener('hashchange', handleHashChange) window.removeEventListener('focus', fetchCollections) } }, []) // 获取当前用户录入的行情数据 const fetchMyDeals = async () => { setDealsLoading(true) const token = localStorage.getItem('token') const userStr = localStorage.getItem('user') if (!token || !userStr) { setDealsLoading(false) return } try { const user = JSON.parse(userStr) const res = await fetch(`${API_BASE}/api/deal/list?user_only=true&page_size=500`, { headers: { 'Authorization': 'Bearer ' + token } }) const data = await res.json() const list = data.data || data || [] setMyDeals(Array.isArray(list) ? list : []) } catch (e) { console.error('获取行情失败:', e) } setDealsLoading(false) } // 切换tab时加载数据 useEffect(() => { if (activeTab === 'deals') { fetchMyDeals() } }, [activeTab]) // 行情过滤和排序 const filteredDeals = myDeals.filter(deal => { if (!dealSearch) return true const s = dealSearch.toLowerCase().trim() const fields = [deal.title, deal.content, deal.category, deal.packaging, deal.grading_company, deal.grading_score, deal.deal_no, deal.seller, deal.platform, deal.buyer, deal.deal_price?.toString(), deal.deal_date].filter(v => v).map(v => v.toString().toLowerCase()) return fields.some(f => f.includes(s)) }).sort((a, b) => { let aVal = a[dealSortField] || '' let bVal = b[dealSortField] || '' if (dealSortField === 'created_at') { aVal = new Date(a.created_at).getTime() bVal = new Date(b.created_at).getTime() } else if (dealSortField === 'deal_price') { aVal = a.deal_price || 0 bVal = b.deal_price || 0 } if (dealSortOrder === 'asc') return aVal > bVal ? 1 : -1 return aVal < bVal ? 1 : -1 }) const fetchCollections = async () => { setLoading(true) const token = localStorage.getItem('token') try { // 从URL获取筛选参数 const params = new URLSearchParams(window.location.hash.split('?')[1] || '') const urlFilterType = params.get('filter') || '' const urlFilterValue = params.get('value') ? decodeURIComponent(params.get('value')) : '' let api = '/api/collections?page=' + page + '&limit=100&sortBy=' + sortField + '&sortOrder=' + sortOrder if (urlFilterType && urlFilterValue) { api += '&' + urlFilterType + '=' + encodeURIComponent(urlFilterValue) } const res = await fetch(api, { headers: token ? { 'Authorization': 'Bearer ' + token } : {} }) // 处理 401 未授权错误 if (res.status === 401) { localStorage.removeItem('token') localStorage.removeItem('user') window.location.hash = '#/login' return } const data = await res.json() // 新格式直接返回数组或 {data: [], pagination: {}} let list = data.data || data if (!Array.isArray(list) && list && Array.isArray(list.items)) { list = list.items } // 应用筛选条件 // 用户ID筛选(从URL获取) if (userIdFilter) { list = list.filter(item => item.userId === userIdFilter || item.userId === userIdFilter.replace(/-/g, '')) } if (filterType && filter) { const fieldMap = { status: 'status', category: 'category', packaging: 'packaging', rarity: 'rarity', numberCategory: 'numberCategory', version: 'version', gradingCompany: 'gradingCompany', gradingScore: 'gradingScore', specialMark: 'specialMark', profitLoss: 'profitLoss' } const field = fieldMap[filterType] || filterType if (filterType === 'profitLoss') { // 盈亏筛选:需要计算出售价和总成本 list = list.filter(item => { if (item.status !== 'sold') return false // 只筛选已售 const totalCost = (item.costPrice || 0) + (item.repairFee || 0) + (item.gradingFee || 0) const isProfit = item.goalPrice > totalCost return filter === 'profit' ? isProfit : !isProfit }) } else { list = list.filter(item => { const value = item[field] || item[filterType] return value === filter }) } console.log(`筛选:${filterType} = ${filter}, 结果:${list.length}条`) } setCollections(list || []) // 获取分页信息 if (data.pagination) { setPagination({ total: data.pagination.total || 0, pages: data.pagination.pages || 1 }) } } catch (e) { console.error('Fetch collections error:', e) // 网络错误也跳转到登录页 localStorage.removeItem('token') localStorage.removeItem('user') window.location.hash = '#/login' } setLoading(false) } // 监听页码变化,重新获取数据 useEffect(() => { if (page > 1) { fetchCollections() } }, [page]) const refresh = () => { setKey(k => k + 1) } useEffect(() => { window.refreshList = refresh return () => { delete window.refreshList } }, []) const goDetail = (id) => { // 保存当前列表的URL(包含筛选条件),用于返回时恢复 sessionStorage.setItem('lastListUrl', window.location.hash.substring(1)) window.location.hash = '#/detail?id=' + id } // 获取筛选字段的中文标签 const getFilterLabel = (type) => { const labels = { status: '状态', category: '持仓类型', packaging: '包装', rarity: '珍惜度', version: '版别', gradingCompany: '评级公司', gradingScore: '评级分数', specialMark: '特殊标识', profitLoss: '盈亏' } return labels[type] || type } // 获取筛选条件值的中文显示 const getFilterValueLabel = (type, value) => { const valueLabels = { status: { in_collection: '收藏中', selling: '出售中', sold: '已售', grading: '送评中', repairing: '修复中', transit: '在途中', seeking: '寻号中', other: '其他' }, category: { 自持: '自持', 寄存: '寄存', 寄售: '寄售', 共有: '共有', 寻号: '寻号', 其他: '其他' }, packaging: { 标十: '标十', 标百: '标百', 单张: '单张', 裸钞: '裸钞' }, rarity: { 通货: '通货', 特色: '特色', 少见: '少见', 稀有: '稀有', 珍品: '珍品', 孤品: '孤品' }, profitLoss: { profit: '盈利', loss: '亏损' }, isGraded: { true: '已评级', false: '未评级' } } const typeLabels = valueLabels[type] if (typeLabels) { return typeLabels[value] || value } return value } const versions = collections && collections.length ? [...new Set(collections.map(c => c.version).filter(v => v))] : [] // 筛选和排序 const filteredCollections = collections.filter(c => { // 筛选条件 if (filter && filterType) { if (filterType === 'profitLoss') { if (c.status !== 'sold') return false if (filter === 'profit') return c.goalPrice > c.costPrice return c.goalPrice <= c.costPrice } else if (filterType === 'isGraded') { if (c.isGraded !== (filter === 'true')) return false } else if (c[filterType] !== filter) { return false } } // 搜索 - 全字段搜索 if (search) { const s = search.toLowerCase().trim() // 收集所有可搜索字段 const allFields = [ // 基本信息 c.name, c.code, c.prefixSerial, c.version, c.status, c.category, c.packaging, c.rarity, // 评级信息 c.gradingCompany, c.gradingScore, c.specialMark, c.isGraded ? '已评级' : '未评级', c.threeStar ? '三星' : '', // 价格信息 c.targetPrice?.toString(), c.costPrice?.toString(), c.goalPrice?.toString(), c.repairFee?.toString(), c.gradingFee?.toString(), // 其他 c.remark, c.purpose, c.material, c.denomination, c.issueYear, c.issueQuantity, c.serialFeature, c.issuer, // 用户信息 c.username || '', c.userId || '' ].filter(v => v !== undefined && v !== null).map(v => v.toString().toLowerCase()) if (!allFields.some(f => f.includes(s))) { return false } } return true }).sort((a, b) => { let aVal = a[sortField] let bVal = b[sortField] if (sortField === 'createdAt') { aVal = new Date(a.createdAt || 0).getTime() bVal = new Date(b.createdAt || 0).getTime() } else if (sortField === 'code') { // 编号按数字排序,提取数字部分 aVal = parseInt(a.code?.replace(/\D/g, '') || '0', 10) bVal = parseInt(b.code?.replace(/\D/g, '') || '0', 10) } else if (sortField === 'prefixSerial') { // 冠字号按字母排序 aVal = a.prefixSerial || '' bVal = b.prefixSerial || '' } else if (['costPrice', 'targetPrice', 'goalPrice', 'gradingScore'].includes(sortField)) { // 价格和分数按数字排序 aVal = parseFloat(aVal) || 0 bVal = parseFloat(bVal) || 0 } else if (sortField === 'rarity') { // 珍惜度按等级排序 const rarityOrder = { '通货': 1, '特色': 2, '少见': 3, '稀有': 4, '珍品': 5, '孤品': 6 } aVal = rarityOrder[aVal] || 0 bVal = rarityOrder[bVal] || 0 } else if (sortField === 'numberCategory') { // 号码分类按自定义顺序排序 const numberCategoryOrder = { '无2347': 1, '无347': 2, '无247': 3, '无47': 4, '带7号': 5, '带4号': 6, '其他': 7 } aVal = numberCategoryOrder[aVal] || 99 bVal = numberCategoryOrder[bVal] || 99 } if (aVal == null) return 1 if (bVal == null) return -1 if (sortOrder === 'asc') { return aVal > bVal ? 1 : -1 } return aVal < bVal ? 1 : -1 }) const clearFilter = () => { setFilter('') setFilterType('') window.location.hash = '#/stats' } const getStatusText = (status) => { const map = { 'in_collection': '收藏中', 'selling': '出售中', 'sold': '已售', 'grading': '送评中', 'repairing': '修复中', 'transit': '在途中', 'seeking': '寻号中', 'other': '其他' } return map[status] || status || '-' } const getCategoryText = (category) => { const map = { '自持': '自持', '寄存': '寄存', '寄售': '寄售', '共有': '共有', '其他': '其他' } return map[category] || category || '自持' } const getCategoryColor = (category) => { const colors = { '自持': '#22c55e', '寄存': '#3b82f6', '寄售': '#f59e0b', '共有': '#8b5cf6', '其他': '#64748b' } return colors[category] || '#64748b' } const getNumberCategoryColor = (cat) => { const colors = { '无2347': '#8b5cf6', '无347': '#ef4444', '无247': '#fbbf24', '无47': '#3b82f6', '带7号': '#06b6d4', '带4号': '#22c55e', '其他': '#64748b' }; return colors[cat] || '#64748b'; }; const getRarityColor = (rarity) => { const colors = { '通货': '#22c55e', '特色': '#06b6d4', '少见': '#3b82f6', '稀有': '#ec4899', '珍品': '#ef4444', '孤品': '#8b5cf6' } return colors[rarity] || '#64748b' } const formatPrefixSerial = (serial) => { if (!serial) return '-' // 提取J开头的10位(1位J + 9位数字) const match = serial.match(/J(\d{9})/) if (match) return 'J' + match[1] // 如果没有J开头,取前10位 return serial.substring(0, 10) } const getPackagingColor = (packaging) => { const colors = { '裸钞': '#22c55e', '单张': '#3b82f6', '标十': '#fbbf24', '标百': '#8b5cf6' } return colors[packaging] || '#64748b' } const getStatusColor = (status) => { const colors = { 'in_collection': '#22c55e', 'selling': '#f59e0b', 'sold': '#ef4444', 'grading': '#8b5cf6', 'repairing': '#f97316', 'transit': '#06b6d4', 'seeking': '#ec4899', 'other': '#64748b' } return colors[status] || '#64748b' } const getVersionColor = (version) => { if (!version) return { bg: 'rgba(255,255,255,0.08)', color: '#94a3b8' } const v = version.toLowerCase() if (v.includes('龙')) return { bg: 'linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%)', color: '#1e293b' } if (v.includes('蛇')) return { bg: 'linear-gradient(135deg, #ec4899 0%, #db2777 100%)', color: '#fff' } if (v.includes('马')) return { bg: 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)', color: '#fff' } if (v.includes('羊')) return { bg: 'linear-gradient(135deg, #f97316 0%, #ea580c 100%)', color: '#fff' } if (v.includes('猴')) return { bg: 'linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)', color: '#fff' } if (v.includes('鸡')) return { bg: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)', color: '#1e293b' } if (v.includes('狗')) return { bg: 'linear-gradient(135deg, #6366f1 0%, #4f46e5 100%)', color: '#fff' } if (v.includes('猪')) return { bg: 'linear-gradient(135deg, #ec4899 0%, #be185d 100%)', color: '#fff' } if (v.includes('鼠')) return { bg: 'linear-gradient(135deg, #64748b 0%, #475569 100%)', color: '#fff' } if (v.includes('牛')) return { bg: 'linear-gradient(135deg, #22c55e 0%, #16a34a 100%)', color: '#fff' } if (v.includes('虎')) return { bg: 'linear-gradient(135deg, #f97316 0%, #ea580c 100%)', color: '#fff' } if (v.includes('兔')) return { bg: 'linear-gradient(135deg, #f43f5e 0%, #e11d48 100%)', color: '#fff' } return { bg: 'linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%)', color: '#1e293b' } } const ListItem = ({ item }) => (
goDetail(item.id)} style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', borderRadius: '12px', padding: '10px', marginBottom: '8px', cursor: 'pointer' }}> {/* 第1行:编号 + 冠字号 + 包装(蓝色) | 状态 + 持仓类型 + 珍惜度(紫色) */}
{item.code || '-'} {formatPrefixSerial(item.prefixSerial)} {item.packaging && {item.packaging}} {item.numberCategory && {item.numberCategory}}
{item.status && {getStatusText(item.status)}} {item.category && {getCategoryText(item.category)}}
{/* 第2行:版本(彩色) + 已评级 + 评级公司 + 评级分数 + 三星 + 特殊标识 | 备注 */}
{item.version && {item.version}} {item.isGraded && 已评级} {item.gradingCompany && {item.gradingCompany.substring(0,4)}} {item.gradingScore && {item.gradingScore}} {item.threeStar && 三星} {item.specialMark && {item.specialMark}}
{item.rarity && {item.rarity}} {item.remark && {item.remark}}
{/* 第3行:成本 + 修复 + 评级 | 目标 + 出售 */}
{item.costPrice && 成本: ¥{item.costPrice}} {item.repairFee && 修复: ¥{item.repairFee}} {item.gradingFee && 评级: ¥{item.gradingFee}}
{item.targetPrice && 目标: ¥{item.targetPrice}} {item.goalPrice && 出售: ¥{item.goalPrice}}
) return (
{filter && filterType && ( )}
v{APP_VERSION}
{filter && filterType && (
当前筛选:
{getFilterLabel(filterType)} = {getFilterValueLabel(filterType, filter)}
)} {activeTab === 'collections' && ( <> {/* 搜索框 - 全字段搜索 */}
setSearch(e.target.value)} style={{ background: 'rgba(255,255,255,0.05)', border: search ? '1px solid rgba(59, 130, 246, 0.5)' : '1px solid rgba(255,255,255,0.1)', color: '#fff', width: '100%', boxSizing: 'border-box', padding: '4px 40px 4px 8px', borderRadius: '12px', fontSize: '14px', outline: 'none', transition: 'border-color 0.2s' }} /> {search && ( )}
{/* 排序表头按钮 */}
排序: {[ { key: 'code', label: '编号' }, { key: 'rarity', label: '珍惜度' }, { key: 'numberCategory', label: '号码分类' }, { key: 'packaging', label: '包装类型' }, ].map(item => (
{ if (sortField === item.key) { setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc') } else { setSortField(item.key) setSortOrder('desc') } }} style={{ padding: '4px 8px', borderRadius: '8px', fontSize: '12px', cursor: 'pointer', background: sortField === item.key ? (sortOrder === 'asc' ? '#22c55e' : '#fbbf24') : 'rgba(255,255,255,0.08)', color: sortField === item.key ? '#fff' : '#94a3b8', fontWeight: sortField === item.key ? 'bold' : 'normal', border: sortField === item.key ? 'none' : '1px solid rgba(255,255,255,0.1)' }}> {item.label} {sortField === item.key && (sortOrder === 'asc' ? '↑' : '↓')}
))}
)} {/* 分页组件 - 仅在藏品tab下显示 */} {activeTab === 'collections' && pagination.pages > 1 && (
{Array.from({ length: Math.min(5, pagination.pages) }, (_, i) => { let startPage = Math.max(1, page - 2) return })} 共{pagination.total}条
)}
{/* 行情tab内容 */} {activeTab === 'deals' && (
{/* 行情搜索框 */}
setDealSearch(e.target.value)} style={{ width: '100%', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', color: '#fff', padding: '10px 12px', borderRadius: '8px', fontSize: '14px', outline: 'none', boxSizing: 'border-box' }} />
{dealsLoading ? (
加载中...
) : filteredDeals.length === 0 ? (
📊
{dealSearch ? '没有匹配的行情' : '暂无行情记录'}
) : (
{filteredDeals.map(deal => ( ))}
)}
)} {/* 藏品tab内容 */} {activeTab === 'collections' && ( <> {loading ? (
加载中...
) : filteredCollections.length === 0 ? (
📭
{filter ? '暂无符合筛选条件的藏品' : '暂无藏品'}
) : viewMode === 'grid' ? (
{filteredCollections.map(item => (
goDetail(item.id)} style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', borderRadius: '12px', padding: '12px', cursor: 'pointer' }}>
🐉
{item.code || '-'}
{formatPrefixSerial(item.prefixSerial)}
{item.gradingScore && {item.gradingScore}} {item.threeStar && ⭐⭐⭐}
))}
) : ( filteredCollections.map(item => ) )} )}
) } // 行情列表项组件 function DealListItem({ deal, onRefresh }) { const [expanded, setExpanded] = useState(false) const [editing, setEditing] = useState(false) const [editForm, setEditForm] = useState({}) const API_BASE = localStorage.getItem('API_BASE') || '' const openEdit = () => { // 从content中解析平台、出售者、购买者 let platform = '', seller = '', buyer = '' if (deal.content) { const platformMatch = deal.content.match(/平台:\s*([^\n]+)/) const sellerMatch = deal.content.match(/出售者:\s*([^\n]+)/) const buyerMatch = deal.content.match(/购买者:\s*([^\n]+)/) if (platformMatch) platform = platformMatch[1].trim() if (sellerMatch) seller = sellerMatch[1].trim() if (buyerMatch) buyer = buyerMatch[1].trim() } setEditForm({ title: deal.title, content: deal.content, deal_price: deal.deal_price, deal_date: deal.deal_date ? (typeof deal.deal_date === 'string' ? deal.deal_date.split('T')[0] : '') : '', packaging: deal.packaging || '单张', is_graded: deal.is_graded || false, grading_company: deal.grading_company || '', grading_score: deal.grading_score || '', category: deal.category || '', deal_no: deal.deal_no || '', platform: platform, seller: seller, buyer: buyer }) setEditing(true) } const saveEdit = async () => { const token = localStorage.getItem('token') try { await fetch(`${API_BASE}/api/deal/${deal.id}`, { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(editForm) }) setEditing(false) onRefresh() } catch(e) { alert('保存失败') } } const deleteDeal = async () => { if (!confirm('确定删除这条行情?')) return const token = localStorage.getItem('token') try { await fetch(`${API_BASE}/api/deal/${deal.id}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }) onRefresh() } catch(e) { alert('删除失败') } } return (
{/* 简要展示 - 两行显示关键信息 */}
setExpanded(!expanded)} style={{ cursor: 'pointer', padding: '10px', background: 'rgba(0,0,0,0.2)', borderRadius: '8px' }}> {/* 第一行:成交日期(月-日)+ 冠字号 + 包装 + 评级分数 + 价格 */}
{deal.deal_date && {deal.deal_date.slice(5)}} {deal.title?.split('-')[0] || '-'} {deal.packaging && {deal.packaging}} {deal.grading_company && {deal.grading_score}} ¥{deal.deal_price?.toLocaleString()}
{/* 第二行:编号 + 分类 + 大小号 + 展开箭头 */}
{deal.deal_no && {deal.deal_no}} {deal.category && {deal.category}} {deal.content && (() => { const sizeMatch = deal.content.match(/大小号:\s*([^\n]+)/) return sizeMatch && {sizeMatch[1]} })()}
{expanded ? '▲ 收起' : '▼展开'}
{/* 展开详情 */} {expanded && (
{editing ? (
{/* 冠字号 */}
冠字号
setEditForm({...editForm, title: `${e.target.value}-¥${editForm.deal_price}`})} style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#fbbf24', fontSize: '14px', fontFamily: 'monospace' }} />
{/* 价格和日期 */}
价格
{ const val = parseFloat(e.target.value) || 0 const serial = editForm.title?.split('-')[0] || '' setEditForm({...editForm, deal_price: val, title: `${serial}-¥${val}`}) }} style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#22c55e', fontSize: '14px' }} />
日期
setEditForm({...editForm, deal_date: e.target.value})} style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#fff', fontSize: '14px' }} />
{/* 包装和分类 */}
包装
分类
setEditForm({...editForm, category: e.target.value})} style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#fff', fontSize: '13px' }} />
{/* 评级 */}
评级机构
评级分数
setEditForm({...editForm, grading_score: e.target.value})} placeholder="如: PC69, 67+" style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#06b6d4', fontSize: '13px' }} />
{/* 平台和出售者购买者 */}
平台
出售者
setEditForm({...editForm, seller: e.target.value})} placeholder="请输入出售者" style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#fff', fontSize: '13px' }} />
购买者
setEditForm({...editForm, buyer: e.target.value})} placeholder="请输入购买者" style={{ width: '100%', padding: '10px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '6px', color: '#fff', fontSize: '13px' }} />
{/* 备注 */}
备注