feat: 资讯页面和发布页面分离,添加信息发布管理功能
This commit is contained in:
parent
80effaaa29
commit
66c086e35d
|
|
@ -494,3 +494,29 @@ def get_my_information_list(
|
||||||
))
|
))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
# ============ 获取当前用户发布的列表 ============
|
||||||
|
@router.get("/my")
|
||||||
|
def get_my_information(
|
||||||
|
page: int = Query(1, ge=1),
|
||||||
|
limit: int = Query(20, ge=1, le=100),
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
"""获取当前用户发布的信息列表"""
|
||||||
|
total = db.query(Information).filter(Information.author == current_user.f01_01_name).count()
|
||||||
|
infos = db.query(Information).filter(
|
||||||
|
Information.author == current_user.f01_01_name
|
||||||
|
).order_by(Information.created_at.desc()).offset((page-1)*limit).limit(limit).all()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"total": total,
|
||||||
|
"list": [{
|
||||||
|
"id": i.id,
|
||||||
|
"title": i.title,
|
||||||
|
"content": i.content,
|
||||||
|
"info_type": i.info_type,
|
||||||
|
"author": i.author,
|
||||||
|
"created_at": i.created_at.isoformat() if i.created_at else None
|
||||||
|
} for i in infos]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import List from './pages/List'
|
||||||
import Add from './pages/Add'
|
import Add from './pages/Add'
|
||||||
import Stats from './pages/Stats'
|
import Stats from './pages/Stats'
|
||||||
import News from './pages/News'
|
import News from './pages/News'
|
||||||
|
import Info from './pages/Info'
|
||||||
import Login from './pages/Login'
|
import Login from './pages/Login'
|
||||||
import Detail from './pages/Detail'
|
import Detail from './pages/Detail'
|
||||||
import Edit from './pages/Edit'
|
import Edit from './pages/Edit'
|
||||||
|
|
@ -30,6 +31,7 @@ export default function App() {
|
||||||
const basePath = path.split('?')[0]
|
const basePath = path.split('?')[0]
|
||||||
if (basePath === '/') return <Home />
|
if (basePath === '/') return <Home />
|
||||||
if (basePath === '/news') return <News />
|
if (basePath === '/news') return <News />
|
||||||
|
if (basePath === '/info') return <Info />
|
||||||
if (basePath === '/stats') return <Stats />
|
if (basePath === '/stats') return <Stats />
|
||||||
if (basePath === '/list') return <List />
|
if (basePath === '/list') return <List />
|
||||||
if (basePath === '/add') return <Add />
|
if (basePath === '/add') return <Add />
|
||||||
|
|
@ -50,6 +52,8 @@ export default function App() {
|
||||||
console.error('Parse user error:', e)
|
console.error('Parse user error:', e)
|
||||||
}
|
}
|
||||||
const isAdmin = user && user.role === 'admin'
|
const isAdmin = user && user.role === 'admin'
|
||||||
|
const isEditor = user && user.role === 'editor'
|
||||||
|
const canAccessInfo = isAdmin || isEditor
|
||||||
|
|
||||||
// 登录页面独立渲染,不显示底部导航
|
// 登录页面独立渲染,不显示底部导航
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
|
@ -88,6 +92,7 @@ export default function App() {
|
||||||
{ path: '/stats', icon: '📊', label: '统计' },
|
{ path: '/stats', icon: '📊', label: '统计' },
|
||||||
{ path: '/list', icon: '📚', label: '藏品' },
|
{ path: '/list', icon: '📚', label: '藏品' },
|
||||||
{ path: '/add', icon: '🎯', label: '添加' },
|
{ path: '/add', icon: '🎯', label: '添加' },
|
||||||
|
...(canAccessInfo ? [{ path: '/info', icon: '📝', label: '信息' }] : []),
|
||||||
...(isAdmin ? [{ path: '/admin', icon: '⚙️', label: '管理' }] : [])
|
...(isAdmin ? [{ path: '/admin', icon: '⚙️', label: '管理' }] : [])
|
||||||
].map(tab => (
|
].map(tab => (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,352 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
// 信息发布页面 - 仅信息员/管理员可用
|
||||||
|
export default function Info() {
|
||||||
|
const [activeTab, setActiveTab] = useState('publish')
|
||||||
|
const [showPublish, setShowPublish] = useState(false)
|
||||||
|
const [myList, setMyList] = useState([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
edition: '龙钞',
|
||||||
|
type: '标百',
|
||||||
|
isGraded: true,
|
||||||
|
category: '成交',
|
||||||
|
source: '直播',
|
||||||
|
prices: {},
|
||||||
|
title: '',
|
||||||
|
content: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 自动生成标题
|
||||||
|
useEffect(() => {
|
||||||
|
const now = new Date()
|
||||||
|
const date = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`
|
||||||
|
const gradeNote = formData.isGraded ? '(评级币)' : '(裸钞)'
|
||||||
|
const title = `「${date} ${formData.edition} ${formData.type} ${formData.category} 行情信息${gradeNote}」`
|
||||||
|
setFormData(prev => ({...prev, title}))
|
||||||
|
}, [formData.edition, formData.type, formData.isGraded, formData.category])
|
||||||
|
|
||||||
|
const API_BASE = localStorage.getItem('API_BASE') || ''
|
||||||
|
|
||||||
|
// 获取我的发布列表
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTab === 'manage') {
|
||||||
|
fetchMyList()
|
||||||
|
}
|
||||||
|
}, [activeTab])
|
||||||
|
|
||||||
|
const fetchMyList = async () => {
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
const res = await fetch(`${API_BASE}/api/information/my`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
|
})
|
||||||
|
const data = await res.json()
|
||||||
|
setMyList(data || [])
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布信息
|
||||||
|
const handlePublish = async () => {
|
||||||
|
if (!formData.title) {
|
||||||
|
alert('请填写标题')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
const gradeNote = formData.isGraded ? '(评级币)' : '(裸钞)'
|
||||||
|
|
||||||
|
let priceContent = ''
|
||||||
|
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()
|
||||||
|
if (data.id || data.code === 0) {
|
||||||
|
alert('发布成功!')
|
||||||
|
setShowPublish(false)
|
||||||
|
setFormData({
|
||||||
|
edition: '龙钞',
|
||||||
|
type: '标百',
|
||||||
|
isGraded: true,
|
||||||
|
category: '成交',
|
||||||
|
source: '直播',
|
||||||
|
prices: {},
|
||||||
|
title: '',
|
||||||
|
content: ''
|
||||||
|
})
|
||||||
|
fetchMyList()
|
||||||
|
} else {
|
||||||
|
alert(data.message || '发布失败')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert('发布失败: ' + e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab切换
|
||||||
|
const tabs = [
|
||||||
|
{ key: 'publish', label: '📝 发布行情' },
|
||||||
|
{ key: 'manage', label: '📋 发布管理' }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 按钮选择组件
|
||||||
|
const ButtonGroup = ({ options, value, onChange, label }) => (
|
||||||
|
<div style={{ marginBottom: '14px' }}>
|
||||||
|
{label && <label style={{ color: '#94a3b8', fontSize: '12px', display: 'block', marginBottom: '6px' }}>{label}</label>}
|
||||||
|
<div style={{ display: 'flex', gap: '8px' }}>
|
||||||
|
{options.map(opt => (
|
||||||
|
<button
|
||||||
|
key={opt.value}
|
||||||
|
onClick={() => onChange(opt.value)}
|
||||||
|
style={{
|
||||||
|
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}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
// 价格网格
|
||||||
|
const PriceGrid = () => {
|
||||||
|
const priceItems = [
|
||||||
|
{ key: 'price_4', label: '带4' },
|
||||||
|
{ key: 'price_no4', label: '无4' },
|
||||||
|
{ key: 'price_no47', label: '无47' },
|
||||||
|
{ key: 'price_no347', label: '无347' },
|
||||||
|
{ key: 'price_no1347', label: '无1347' },
|
||||||
|
{ key: 'price_no247', label: '无247' },
|
||||||
|
{ key: 'price_no1247', label: '无1247' },
|
||||||
|
{ key: 'price_no12347', label: '无12347' }
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: '14px' }}>
|
||||||
|
<label style={{ color: '#94a3b8', fontSize: '12px', display: 'block', marginBottom: '6px' }}>价格(可选)</label>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '8px' }}>
|
||||||
|
{priceItems.map(item => (
|
||||||
|
<div key={item.key}>
|
||||||
|
<label style={{ color: '#64748b', fontSize: '11px' }}>{item.label}</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={formData.prices?.[item.key] || ''}
|
||||||
|
onChange={(e) => setFormData({
|
||||||
|
...formData,
|
||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (dateStr) => {
|
||||||
|
if (!dateStr) return '-'
|
||||||
|
const date = new Date(dateStr)
|
||||||
|
return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ minHeight: '100vh', background: '#0f172a', paddingBottom: '60px' }}>
|
||||||
|
{/* Tab导航 */}
|
||||||
|
<div style={{ display: 'flex', padding: '12px 16px', background: '#1e293b', gap: '8px', overflowX: 'auto' }}>
|
||||||
|
{tabs.map(tab => (
|
||||||
|
<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>
|
||||||
|
|
||||||
|
{/* 发布行情 */}
|
||||||
|
{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 }}>
|
||||||
|
<label style={{ color: '#94a3b8', fontSize: '12px' }}>类型 *</label>
|
||||||
|
<div style={{ display: 'flex', gap: '6px', marginTop: '6px' }}>
|
||||||
|
{['标百', '标十', '单张'].map(t => (
|
||||||
|
<button key={t} onClick={() => setFormData({...formData, type: t})}
|
||||||
|
style={{ flex: 1, padding: '10px', borderRadius: '6px',
|
||||||
|
border: formData.type === t ? '2px solid #fbbf24' : '1px solid #334155',
|
||||||
|
background: formData.type === t ? 'rgba(251,191,36,0.2)' : '#0f172a',
|
||||||
|
color: '#fff', cursor: 'pointer', fontSize: '13px' }}>
|
||||||
|
{t}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<label style={{ color: '#94a3b8', fontSize: '12px' }}>是否评级</label>
|
||||||
|
<button onClick={() => setFormData({...formData, isGraded: !formData.isGraded})}
|
||||||
|
style={{ width: '100%', padding: '10px', marginTop: '6px', borderRadius: '6px',
|
||||||
|
border: formData.isGraded ? '2px solid #fbbf24' : '1px solid #334155',
|
||||||
|
background: formData.isGraded ? 'rgba(251,191,36,0.2)' : '#0f172a',
|
||||||
|
color: formData.isGraded ? '#fbbf24' : '#94a3b8', cursor: 'pointer', fontSize: '13px' }}>
|
||||||
|
{formData.isGraded ? '✅ 评级' : '○ 未评级'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ButtonGroup label="分类 *" options={[
|
||||||
|
{ value: '成交', label: '💰 成交' },
|
||||||
|
{ value: '求购', label: '🔍 求购' },
|
||||||
|
{ value: '出售', label: '💵 出售' }
|
||||||
|
]} value={formData.category} onChange={(v) => setFormData({...formData, category: v})} />
|
||||||
|
|
||||||
|
<ButtonGroup label="信息源 *" options={[
|
||||||
|
{ value: '直播', label: '📺 直播' },
|
||||||
|
{ value: '一尘', label: '💼 一尘' },
|
||||||
|
{ value: '爱藏', label: '📦 爱藏' },
|
||||||
|
{ value: '其他', label: '📋 其他' }
|
||||||
|
]} value={formData.source} onChange={(v) => setFormData({...formData, source: v})} />
|
||||||
|
|
||||||
|
<PriceGrid />
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '14px' }}>
|
||||||
|
<label style={{ color: '#94a3b8', fontSize: '12px' }}>标题(自动生成)</label>
|
||||||
|
<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>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,47 +1,26 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
// 资讯页面 - 寻配号、成交数据、发布中心
|
// 资讯页面 - 展示寻配号和行情信息(所有人可见)
|
||||||
export default function News() {
|
export default function News() {
|
||||||
const [activeTab, setActiveTab] = useState('seek') // seek-寻配号, deal-成交, publish-发布
|
const [activeTab, setActiveTab] = useState('seek')
|
||||||
const [infoList, setInfoList] = useState([])
|
const [infoList, setInfoList] = useState([])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [showPublish, setShowPublish] = useState(false)
|
|
||||||
const [myList, setMyList] = useState([])
|
|
||||||
|
|
||||||
// 发布表单
|
|
||||||
const [formData, setFormData] = useState({
|
|
||||||
info_type: 'seek',
|
|
||||||
title: '',
|
|
||||||
content: '',
|
|
||||||
collection_id: '',
|
|
||||||
expect_category: '',
|
|
||||||
expect_version: '',
|
|
||||||
expect_packaging: '',
|
|
||||||
expect_number: '',
|
|
||||||
expect_price_min: '',
|
|
||||||
expect_price_max: '',
|
|
||||||
deal_price: '',
|
|
||||||
deal_date: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
// 我的藏品列表(用于关联)
|
|
||||||
const [myCollections, setMyCollections] = useState([])
|
|
||||||
|
|
||||||
const API_BASE = localStorage.getItem('API_BASE') || ''
|
const API_BASE = localStorage.getItem('API_BASE') || ''
|
||||||
|
|
||||||
|
// 获取资讯列表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchInfoList()
|
fetchInfoList()
|
||||||
fetchMyCollections()
|
|
||||||
fetchMyList()
|
|
||||||
}, [activeTab])
|
}, [activeTab])
|
||||||
|
|
||||||
// 获取资讯列表
|
|
||||||
const fetchInfoList = async () => {
|
const fetchInfoList = 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/list?info_type=${activeTab}`, {
|
// 根据tab获取不同类型的数据
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
const type = activeTab === 'seek' ? 'seek' : 'deal'
|
||||||
|
const res = await fetch(`${API_BASE}/api/information/list?info_type=${type}`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
setInfoList(data || [])
|
setInfoList(data || [])
|
||||||
|
|
@ -51,141 +30,34 @@ export default function News() {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取我的藏品列表
|
// Tab切换
|
||||||
const fetchMyCollections = async () => {
|
const tabs = [
|
||||||
try {
|
{ key: 'seek', label: '🔍 寻配号' },
|
||||||
const token = localStorage.getItem('token')
|
{ key: 'deal', label: '💰 成交行情' }
|
||||||
const res = await fetch(`${API_BASE}/api/collections?page=1&page_size=100`, {
|
]
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
|
||||||
})
|
|
||||||
const data = await res.json()
|
|
||||||
setMyCollections(data.items || [])
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取我的发布列表
|
|
||||||
const fetchMyList = async () => {
|
|
||||||
try {
|
|
||||||
const token = localStorage.getItem('token')
|
|
||||||
const res = await fetch(`${API_BASE}/api/information/my/list`, {
|
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
|
||||||
})
|
|
||||||
const data = await res.json()
|
|
||||||
setMyList(data || [])
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发布资讯
|
|
||||||
const handlePublish = async () => {
|
|
||||||
if (!formData.title) {
|
|
||||||
alert('请输入标题')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const token = localStorage.getItem('token')
|
|
||||||
const res = await fetch(`${API_BASE}/api/information/`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${token}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
...formData,
|
|
||||||
expect_price_min: formData.expect_price_min ? parseFloat(formData.expect_price_min) : null,
|
|
||||||
expect_price_max: formData.expect_price_max ? parseFloat(formData.expect_price_max) : null,
|
|
||||||
deal_price: formData.deal_price ? parseFloat(formData.deal_price) : null,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if (res.ok) {
|
|
||||||
alert('发布成功!')
|
|
||||||
setShowPublish(false)
|
|
||||||
setFormData({
|
|
||||||
info_type: 'seek',
|
|
||||||
title: '',
|
|
||||||
content: '',
|
|
||||||
collection_id: '',
|
|
||||||
expect_category: '',
|
|
||||||
expect_version: '',
|
|
||||||
expect_packaging: '',
|
|
||||||
expect_number: '',
|
|
||||||
expect_price_min: '',
|
|
||||||
expect_price_max: '',
|
|
||||||
deal_price: '',
|
|
||||||
deal_date: ''
|
|
||||||
})
|
|
||||||
fetchInfoList()
|
|
||||||
fetchMyList()
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
alert('发布失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除发布
|
|
||||||
const handleDelete = async (id) => {
|
|
||||||
if (!confirm('确定删除?')) return
|
|
||||||
try {
|
|
||||||
const token = localStorage.getItem('token')
|
|
||||||
await fetch(`${API_BASE}/api/information/${id}`, {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: { 'Authorization': `Bearer ${token}` }
|
|
||||||
})
|
|
||||||
fetchMyList()
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化日期
|
|
||||||
const formatDate = (dateStr) => {
|
const formatDate = (dateStr) => {
|
||||||
if (!dateStr) return ''
|
if (!dateStr) return '-'
|
||||||
return new Date(dateStr).toLocaleDateString('zh-CN')
|
const date = new Date(dateStr)
|
||||||
}
|
return `${date.getMonth() + 1}/${date.getDate()}`
|
||||||
|
|
||||||
// 资讯类型映射
|
|
||||||
const typeMap = {
|
|
||||||
seek: '寻配号',
|
|
||||||
deal: '成交数据',
|
|
||||||
publish: '发布'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '16px', paddingBottom: '80px', minHeight: '100vh', background: '#0f172a' }}>
|
<div style={{ minHeight: '100vh', background: '#0f172a', paddingBottom: '60px' }}>
|
||||||
{/* 顶部标题 */}
|
{/* Tab导航 */}
|
||||||
<div style={{ textAlign: 'center', marginBottom: '16px' }}>
|
<div style={{ display: 'flex', padding: '12px 16px', background: '#1e293b', gap: '8px', overflowX: 'auto' }}>
|
||||||
<h1 style={{ fontSize: '20px', color: '#fbbf24', margin: 0 }}>📰 资讯中心</h1>
|
{tabs.map(tab => (
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 二级标签切换 */}
|
|
||||||
<div style={{
|
|
||||||
display: 'flex',
|
|
||||||
background: '#1e293b',
|
|
||||||
borderRadius: '8px',
|
|
||||||
padding: '4px',
|
|
||||||
marginBottom: '16px'
|
|
||||||
}}>
|
|
||||||
{[
|
|
||||||
{ key: 'seek', label: '🔍 寻配号' },
|
|
||||||
{ key: 'deal', label: '📈 成交数据' },
|
|
||||||
{ key: 'publish', label: '➕ 发布' }
|
|
||||||
].map(tab => (
|
|
||||||
<div
|
<div
|
||||||
key={tab.key}
|
key={tab.key}
|
||||||
onClick={() => setActiveTab(tab.key)}
|
onClick={() => setActiveTab(tab.key)}
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
padding: '10px 20px',
|
||||||
textAlign: 'center',
|
borderRadius: '8px',
|
||||||
padding: '10px',
|
|
||||||
borderRadius: '6px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
background: activeTab === tab.key ? '#3b82f6' : 'transparent',
|
background: activeTab === tab.key ? '#3b82f6' : 'transparent',
|
||||||
color: activeTab === tab.key ? '#fff' : '#94a3b8',
|
color: '#fff',
|
||||||
fontSize: '14px',
|
cursor: 'pointer',
|
||||||
fontWeight: activeTab === tab.key ? 'bold' : 'normal'
|
whiteSpace: 'nowrap',
|
||||||
|
fontSize: '14px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tab.label}
|
{tab.label}
|
||||||
|
|
@ -193,508 +65,38 @@ export default function News() {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 发布按钮 */}
|
|
||||||
{activeTab !== 'publish' && (
|
|
||||||
<div style={{ marginBottom: '16px', textAlign: 'right' }}>
|
|
||||||
<button
|
|
||||||
onClick={() => setShowPublish(!showPublish)}
|
|
||||||
style={{
|
|
||||||
background: '#3b82f6',
|
|
||||||
color: '#fff',
|
|
||||||
border: 'none',
|
|
||||||
padding: '8px 16px',
|
|
||||||
borderRadius: '6px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: '14px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{showPublish ? '取消发布' : '➕ 发布'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 发布表单 */}
|
|
||||||
{showPublish && (
|
|
||||||
<div style={{
|
|
||||||
background: '#1e293b',
|
|
||||||
borderRadius: '12px',
|
|
||||||
padding: '16px',
|
|
||||||
marginBottom: '16px'
|
|
||||||
}}>
|
|
||||||
<h3 style={{ color: '#fbbf24', marginTop: 0 }}>发布信息</h3>
|
|
||||||
|
|
||||||
{/* 选择类型 */}
|
|
||||||
<div style={{ marginBottom: '12px' }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>类型</label>
|
|
||||||
<select
|
|
||||||
value={formData.info_type}
|
|
||||||
onChange={(e) => setFormData({...formData, info_type: e.target.value})}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="seek">🔍 寻配号</option>
|
|
||||||
<option value="deal">📈 成交数据</option>
|
|
||||||
<option value="publish">📝 普通发布</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 标题 */}
|
|
||||||
<div style={{ marginBottom: '12px' }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>标题 *</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.title}
|
|
||||||
onChange={(e) => setFormData({...formData, title: e.target.value})}
|
|
||||||
placeholder="请输入标题"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 内容 */}
|
|
||||||
<div style={{ marginBottom: '12px' }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>详细描述</label>
|
|
||||||
<textarea
|
|
||||||
value={formData.content}
|
|
||||||
onChange={(e) => setFormData({...formData, content: e.target.value})}
|
|
||||||
placeholder="请输入详细描述..."
|
|
||||||
rows={3}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
resize: 'vertical'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 关联藏品 */}
|
|
||||||
{formData.info_type === 'seek' && (
|
|
||||||
<div style={{ marginBottom: '12px' }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>关联我的藏品(可选)</label>
|
|
||||||
<select
|
|
||||||
value={formData.collection_id}
|
|
||||||
onChange={(e) => setFormData({...formData, collection_id: e.target.value})}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="">不关联</option>
|
|
||||||
{myCollections.map(c => (
|
|
||||||
<option key={c.f99_90_id} value={c.f99_90_id}>
|
|
||||||
{c.f01_01_name} - {c.f01_03_category}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 寻配号条件 */}
|
|
||||||
{formData.info_type === 'seek' && (
|
|
||||||
<>
|
|
||||||
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>期望类别</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_category}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_category: e.target.value})}
|
|
||||||
placeholder="如:纪念钞"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>期望版别</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_version}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_version: e.target.value})}
|
|
||||||
placeholder="如:2024版"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>期望包装</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_packaging}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_packaging: e.target.value})}
|
|
||||||
placeholder="如:散钞"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>期望号码</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_number}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_number: e.target.value})}
|
|
||||||
placeholder="如:888"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>最低价格</label>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={formData.expect_price_min}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_price_min: e.target.value})}
|
|
||||||
placeholder="0"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>最高价格</label>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={formData.expect_price_max}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_price_max: e.target.value})}
|
|
||||||
placeholder="0"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 成交数据 */}
|
|
||||||
{formData.info_type === 'deal' && (
|
|
||||||
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>成交价格</label>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={formData.deal_price}
|
|
||||||
onChange={(e) => setFormData({...formData, deal_price: e.target.value})}
|
|
||||||
placeholder="成交金额"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>版别</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_version}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_version: e.target.value})}
|
|
||||||
placeholder="如:2024版"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1 }}>
|
|
||||||
<label style={{ color: '#94a3b8', fontSize: '12px' }}>包装</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.expect_packaging}
|
|
||||||
onChange={(e) => setFormData({...formData, expect_packaging: e.target.value})}
|
|
||||||
placeholder="如:标十"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px',
|
|
||||||
background: '#0f172a',
|
|
||||||
border: '1px solid #334155',
|
|
||||||
borderRadius: '6px',
|
|
||||||
color: '#fff',
|
|
||||||
marginTop: '4px',
|
|
||||||
boxSizing: 'border-box'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={handlePublish}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
padding: '12px',
|
|
||||||
background: '#3b82f6',
|
|
||||||
color: '#fff',
|
|
||||||
border: 'none',
|
|
||||||
borderRadius: '6px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: '16px',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
发布
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 资讯列表 */}
|
{/* 资讯列表 */}
|
||||||
{activeTab === 'publish' ? (
|
<div style={{ padding: '16px' }}>
|
||||||
// 我的发布
|
<h3 style={{ color: '#fff', marginBottom: '16px' }}>
|
||||||
<div>
|
{activeTab === 'seek' ? '🔍 寻配号信息' : '💰 成交行情信息'}
|
||||||
<h3 style={{ color: '#fbbf24', marginBottom: '12px' }}>我的发布</h3>
|
</h3>
|
||||||
{loading ? (
|
|
||||||
<div style={{ textAlign: 'center', color: '#94a3b8', padding: '20px' }}>加载中...</div>
|
{loading ? (
|
||||||
) : myList.length === 0 ? (
|
<div style={{ color: '#94a3b8', textAlign: 'center', padding: '40px' }}>加载中...</div>
|
||||||
<div style={{ textAlign: 'center', color: '#94a3b8', padding: '20px' }}>暂无发布</div>
|
) : infoList.length === 0 ? (
|
||||||
) : (
|
<div style={{ color: '#94a3b8', textAlign: 'center', padding: '40px' }}>
|
||||||
myList.map(item => (
|
暂无{activeTab === 'seek' ? '寻配号' : '成交行情'}信息
|
||||||
<div key={item.id} style={{
|
</div>
|
||||||
background: '#1e293b',
|
) : (
|
||||||
borderRadius: '12px',
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
|
||||||
padding: '16px',
|
{infoList.map(item => (
|
||||||
marginBottom: '12px'
|
<div key={item.id} style={{ background: '#1e293b', borderRadius: '12px', padding: '16px' }}>
|
||||||
}}>
|
<div style={{ color: '#fbbf24', fontSize: '15px', fontWeight: '500', marginBottom: '8px' }}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
{item.title}
|
||||||
<span style={{
|
|
||||||
background: item.info_type === 'seek' ? '#3b82f6' : item.info_type === 'deal' ? '#10b981' : '#f59e0b',
|
|
||||||
color: '#fff',
|
|
||||||
padding: '2px 8px',
|
|
||||||
borderRadius: '4px',
|
|
||||||
fontSize: '12px'
|
|
||||||
}}>
|
|
||||||
{typeMap[item.info_type]}
|
|
||||||
</span>
|
|
||||||
<button
|
|
||||||
onClick={() => handleDelete(item.id)}
|
|
||||||
style={{
|
|
||||||
background: '#ef4444',
|
|
||||||
color: '#fff',
|
|
||||||
border: 'none',
|
|
||||||
padding: '4px 8px',
|
|
||||||
borderRadius: '4px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: '12px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<h4 style={{ color: '#fff', margin: '8px 0' }}>{item.title}</h4>
|
<div style={{ color: '#94a3b8', fontSize: '12px', marginBottom: '8px' }}>
|
||||||
<p style={{ color: '#94a3b8', fontSize: '13px', margin: 0 }}>{item.content}</p>
|
{formatDate(item.created_at)} | {item.info_source || '系统'}
|
||||||
<div style={{ color: '#64748b', fontSize: '12px', marginTop: '8px' }}>
|
|
||||||
{formatDate(item.created_at)} · 浏览 {item.view_count} · 联系 {item.contact_count}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
// 寻配号 / 成交数据列表
|
|
||||||
<div>
|
|
||||||
{loading ? (
|
|
||||||
<div style={{ textAlign: 'center', color: '#94a3b8', padding: '20px' }}>加载中...</div>
|
|
||||||
) : infoList.length === 0 ? (
|
|
||||||
<div style={{ textAlign: 'center', color: '#94a3b8', padding: '20px' }}>
|
|
||||||
暂无{activeTab === 'seek' ? '寻配号' : '成交数据'}信息
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
infoList.map(item => (
|
|
||||||
<div key={item.id} style={{
|
|
||||||
background: '#1e293b',
|
|
||||||
borderRadius: '12px',
|
|
||||||
padding: '16px',
|
|
||||||
marginBottom: '12px'
|
|
||||||
}}>
|
|
||||||
{/* 用户信息 */}
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '8px' }}>
|
|
||||||
<div style={{
|
|
||||||
width: '32px',
|
|
||||||
height: '32px',
|
|
||||||
borderRadius: '50%',
|
|
||||||
background: '#3b82f6',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: '14px',
|
|
||||||
marginRight: '8px'
|
|
||||||
}}>
|
|
||||||
{item.user_name ? item.user_name[0] : '?'}
|
|
||||||
</div>
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '13px' }}>{item.user_name}</span>
|
|
||||||
<span style={{ color: '#64748b', fontSize: '12px', marginLeft: 'auto' }}>
|
|
||||||
{formatDate(item.created_at)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 标题 */}
|
|
||||||
<h4 style={{ color: '#fff', margin: '0 0 8px 0', fontSize: '16px' }}>{item.title}</h4>
|
|
||||||
|
|
||||||
{/* 内容 */}
|
|
||||||
{item.content && (
|
{item.content && (
|
||||||
<p style={{ color: '#94a3b8', fontSize: '14px', margin: '0 0 8px 0' }}>{item.content}</p>
|
<div style={{ color: '#e2e8f0', fontSize: '14px', lineHeight: '1.6' }}>
|
||||||
)}
|
{item.content}
|
||||||
|
|
||||||
{/* 寻配号条件 */}
|
|
||||||
{item.info_type === 'seek' && (item.expect_category || item.expect_version || item.expect_number) && (
|
|
||||||
<div style={{
|
|
||||||
background: '#0f172a',
|
|
||||||
borderRadius: '8px',
|
|
||||||
padding: '12px',
|
|
||||||
marginBottom: '8px'
|
|
||||||
}}>
|
|
||||||
<div style={{ color: '#fbbf24', fontSize: '12px', marginBottom: '4px' }}>期望条件</div>
|
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
|
|
||||||
{item.expect_category && (
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '12px' }}>类别: {item.expect_category}</span>
|
|
||||||
)}
|
|
||||||
{item.expect_version && (
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '12px' }}>版别: {item.expect_version}</span>
|
|
||||||
)}
|
|
||||||
{item.expect_packaging && (
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '12px' }}>包装: {item.expect_packaging}</span>
|
|
||||||
)}
|
|
||||||
{item.expect_number && (
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '12px' }}>号码: {item.expect_number}</span>
|
|
||||||
)}
|
|
||||||
{(item.expect_price_min || item.expect_price_max) && (
|
|
||||||
<span style={{ color: '#94a3b8', fontSize: '12px' }}>
|
|
||||||
价格: {item.expect_price_min || '?'} - {item.expect_price_max || '?'}元
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 成交数据 */}
|
|
||||||
{item.info_type === 'deal' && (
|
|
||||||
<div style={{
|
|
||||||
background: '#0f172a',
|
|
||||||
borderRadius: '8px',
|
|
||||||
padding: '12px',
|
|
||||||
marginBottom: '8px'
|
|
||||||
}}>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
||||||
<span style={{ color: '#10b981', fontSize: '18px', fontWeight: 'bold' }}>
|
|
||||||
¥{item.deal_price || '-'}
|
|
||||||
</span>
|
|
||||||
<span style={{ color: '#64748b', fontSize: '12px' }}>
|
|
||||||
{item.expect_version} / {item.expect_packaging}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 关联藏品 */}
|
|
||||||
{item.collection_name && (
|
|
||||||
<div style={{
|
|
||||||
background: '#3b82f620',
|
|
||||||
borderRadius: '8px',
|
|
||||||
padding: '8px 12px',
|
|
||||||
marginBottom: '8px',
|
|
||||||
borderLeft: '3px solid #3b82f6'
|
|
||||||
}}>
|
|
||||||
<span style={{ color: '#3b82f6', fontSize: '12px' }}>关联藏品: </span>
|
|
||||||
<span style={{ color: '#fff', fontSize: '13px' }}>{item.collection_name}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 统计 */}
|
|
||||||
<div style={{ display: 'flex', gap: '16px', color: '#64748b', fontSize: '12px' }}>
|
|
||||||
<span>👁 {item.view_count}</span>
|
|
||||||
<span>📞 {item.contact_count}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))
|
))}
|
||||||
)}
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue