diff --git a/VERSION b/VERSION
index d659080..1ce7217 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-VERSION=1.2.59
+VERSION=1.2.41
diff --git a/backend/app/main.py b/backend/app/main.py
index 1b33e39..2ec184f 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -52,11 +52,10 @@ app = FastAPI(
# 设置全局错误处理器
setup_error_handlers(app)
-# CORS 配置 - 生产环境限制域名
-ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "http://47.103.29.111,http://120.55.81.21,https://socoolbot.com").split(",")
+# CORS 配置
app.add_middleware(
CORSMiddleware,
- allow_origins=ALLOWED_ORIGINS, # 生产环境限制域名
+ allow_origins=["*"], # 生产环境应该限制域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
@@ -67,10 +66,10 @@ uploads_dir = "uploads"
os.makedirs(uploads_dir, exist_ok=True)
app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads")
-# 挂载项目静态资源目录(可选,生产环境建议用 Nginx)
-# static_dir = Path(__file__).parent.parent.parent / "static"
-# if static_dir.exists():
-# app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
+# 挂载项目静态资源目录
+static_dir = Path(__file__).parent.parent / "static"
+if static_dir.exists():
+ app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
# 添加日志中间件
app.middleware("http")(logging_middleware)
@@ -82,7 +81,7 @@ app.include_router(operations.router)
app.include_router(ocr_router.router) # OCR 识别
app.include_router(users_router.router) # 当前用户接口
app.include_router(users_router.admin_router) # 管理员用户管理
-app.include_router(information_router.router) # 资讯
+app.include_router(information_router.router)
app.include_router(yichens_router.router) # 一尘看板
diff --git a/backend/app/models/models.py b/backend/app/models/models.py
index 40811e7..387f670 100644
--- a/backend/app/models/models.py
+++ b/backend/app/models/models.py
@@ -163,7 +163,7 @@ class Information(Base):
# 内容描述
content = Column(Text, nullable=True)
-
+
# 关联藏品ID
collection_id = Column(String(36), ForeignKey("collections.f99_90_id", ondelete="SET NULL"), nullable=True)
diff --git a/backend/app/routers/information.py b/backend/app/routers/information.py
index 7fb9484..a249fbb 100644
--- a/backend/app/routers/information.py
+++ b/backend/app/routers/information.py
@@ -1,12 +1,14 @@
# 资讯API路由
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, joinedload
+from sqlalchemy import text
from typing import List, Optional
from pydantic import BaseModel
from datetime import datetime, date
from app.core.database import get_db
from app.core.auth import get_current_user
+from app.core.coolbot_db import coolbot_engine
from app.models.models import User, Information, Collection
router = APIRouter(prefix="/api/information", tags=["资讯"])
@@ -16,7 +18,7 @@ router = APIRouter(prefix="/api/information", tags=["资讯"])
class InformationCreate(BaseModel):
info_type: str # seek-寻配号, deal-成交数据, publish-发布
title: str
- content: Optional[str] = None
+ content: Optional[str]
collection_id: Optional[str] = None
expect_category: Optional[str] = None
expect_version: Optional[str] = None
@@ -30,7 +32,7 @@ class InformationCreate(BaseModel):
class InformationUpdate(BaseModel):
title: Optional[str] = None
- content: Optional[str] = None
+ content: Optional[str]
status: Optional[str] = None
expect_category: Optional[str] = None
expect_version: Optional[str] = None
@@ -74,6 +76,8 @@ class InformationResponse(BaseModel):
collection_number: Optional[str] = None
# 匹配数量(我的藏品中满足条件的数量)
matched_count: Optional[int] = 0
+ # 网络数据匹配数量(coolbot_data数据库中满足条件的数量)
+ network_matched_count: Optional[int] = 0
class Config:
from_attributes = True
@@ -87,7 +91,8 @@ def get_information_list(
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100),
current_user: Optional[User] = Depends(get_current_user),
- db: Session = Depends(get_db)
+ db: Session = Depends(get_db),
+ response: Response = None
):
"""获取资讯列表(公开,无需登录)"""
query = db.query(Information).options(
@@ -142,8 +147,21 @@ def get_information_list(
collection_version=item.collection.f02_11_version if item.collection else None,
collection_number=item.collection.f02_10_prefix_serial if item.collection else None,
matched_count=matched_count,
+ network_matched_count=match_collections_count_from_coolbot(item.expect_number) if item.info_type == 'seek' and item.expect_number else 0,
))
+ # 获取总数并设置响应头
+ from fastapi import Response
+ total_query = db.query(Information).filter(Information.status == status)
+ if info_type:
+ total_query = total_query.filter(Information.info_type == info_type)
+ total_count = total_query.count()
+ total_pages = (total_count + page_size - 1) // page_size
+
+ # 设置响应头
+ response.headers['X-Total-Pages'] = str(total_pages)
+ response.headers['X-Total-Count'] = str(total_count)
+
return result
@@ -182,6 +200,110 @@ def match_collections_count(db: Session, user_id: str, expect_number: str) -> in
return count
+def match_collections_count_from_coolbot(expect_number: str) -> int:
+ """根据号码特征计算匹配藏品数量(从coolbot_data数据库)"""
+ if not expect_number or len(expect_number) != 10:
+ return 0
+
+ # 固定前缀
+ if not expect_number.startswith('J0'):
+ return 0
+
+ pattern = expect_number[2:] # 后8位
+ if not pattern:
+ return 0
+
+ # 直接查询coolbot_data数据库
+ query = text("""
+ SELECT COUNT(*) FROM collections
+ WHERE crown_code IS NOT NULL
+ AND crown_code != ''
+ AND LENGTH(crown_code) >= 10
+ AND crown_code LIKE 'J0%'
+ """)
+
+ try:
+ with coolbot_engine.connect() as conn:
+ result = conn.execute(query)
+ total_count = result.scalar() or 0
+
+ # 遍历匹配
+ query_all = text("""
+ SELECT id, crown_code FROM collections
+ WHERE crown_code IS NOT NULL
+ AND crown_code != ''
+ AND LENGTH(crown_code) >= 10
+ AND crown_code LIKE 'J0%'
+ """)
+ result = conn.execute(query_all)
+
+ match_count = 0
+ for row in result:
+ crown_code = row[1]
+ if crown_code and len(crown_code) >= 10:
+ col_pattern = crown_code[2:10]
+ if match_pattern(col_pattern, pattern):
+ match_count += 1
+
+ return match_count
+ except Exception as e:
+ print(f"Error querying coolbot_data: {e}")
+ return 0
+
+
+def match_collections_list_from_coolbot(expect_number: str, limit: int = 20) -> List[dict]:
+ """获取匹配的藏品列表(从coolbot_data数据库)"""
+ if not expect_number or len(expect_number) != 10:
+ return []
+
+ # 固定前缀
+ if not expect_number.startswith('J0'):
+ return []
+
+ pattern = expect_number[2:] # 后8位
+ if not pattern:
+ return []
+
+ # 直接查询coolbot_data数据库
+ query = text("""
+ SELECT id, name, category, crown_code, price, post_title, post_url, author, post_crawled_at
+ FROM collections
+ WHERE crown_code IS NOT NULL
+ AND crown_code != ''
+ AND LENGTH(crown_code) >= 10
+ AND crown_code LIKE 'J0%'
+ """)
+
+ try:
+ with coolbot_engine.connect() as conn:
+ result = conn.execute(query)
+
+ matched = []
+ for row in result:
+ crown_code = row[3]
+ if crown_code and len(crown_code) >= 10:
+ col_pattern = crown_code[2:10]
+ if match_pattern(col_pattern, pattern):
+ matched.append({
+ "id": row[0],
+ "name": row[1],
+ "category": row[2],
+ "crown_code": crown_code,
+ "price": float(row[4]) if row[4] else None,
+ "post_title": row[5],
+ "post_url": row[6],
+ "author": row[7],
+ "post_crawled_at": row[8].isoformat() if row[8] else None
+ })
+ if len(matched) >= limit:
+ break
+
+ return matched
+ except Exception as e:
+ print(f"Error querying coolbot_data: {e}")
+ return []
+
+
def match_pattern(col_number: str, pattern: str) -> bool:
"""匹配号码特征模式"""
# X = 任意数字
@@ -502,7 +624,36 @@ def get_seek_match(
"cost_price": c.f05_40_cost_price,
}
for c in matched
- ]
+ ],
+ "network_matched_count": match_collections_count_from_coolbot(info.expect_number) if info.expect_number else 0,
+ "network_collections": match_collections_list_from_coolbot(info.expect_number, limit=20) if info.expect_number else []
+ }
+
+
+# 获取网络数据匹配列表
+@router.get("/seek/network-match/{info_id}")
+def get_network_match(
+ info_id: str,
+ limit: int = Query(20, ge=1, le=100),
+ db: Session = Depends(get_db)
+):
+ """获取一尘数据库中匹配的藏品列表"""
+ info = db.query(Information).filter(
+ Information.id == info_id,
+ Information.info_type == "seek"
+ ).first()
+
+ if not info:
+ raise HTTPException(status_code=404, detail="寻配号信息不存在")
+
+ if not info.expect_number:
+ return {"matched_count": 0, "collections": []}
+
+ matched = match_collections_list_from_coolbot(info.expect_number, limit=limit)
+
+ return {
+ "matched_count": len(matched),
+ "collections": matched
}
@@ -558,8 +709,21 @@ def get_my_seeks(
collection_version=item.collection.f02_11_version if item.collection else None,
collection_number=item.collection.f02_10_prefix_serial if item.collection else None,
matched_count=matched_count,
+ network_matched_count=match_collections_count_from_coolbot(item.expect_number) if item.info_type == 'seek' and item.expect_number else 0,
))
+ # 获取总数并设置响应头
+ from fastapi import Response
+ total_query = db.query(Information).filter(Information.status == status)
+ if info_type:
+ total_query = total_query.filter(Information.info_type == info_type)
+ total_count = total_query.count()
+ total_pages = (total_count + page_size - 1) // page_size
+
+ # 设置响应头
+ response.headers['X-Total-Pages'] = str(total_pages)
+ response.headers['X-Total-Count'] = str(total_count)
+
return result
@@ -891,3 +1055,18 @@ def get_publisher_info(
"contact": contact,
"created_at": info.created_at.isoformat() if info.created_at else None
}
+
+
+@router.get("/yichen-posts")
+def get_yichen_posts(category: str = None, search: str = None, page: int = 1, page_size: int = 20):
+ from app.models.models import Information
+ from sqlalchemy import desc
+ query = db.query(Information).filter(Information.info_type == 'yichen')
+ if category:
+ query = query.filter(Information.expect_category == category)
+ if search:
+ query = query.filter(Information.title.contains(search))
+ total = query.count()
+ offset = (page - 1) * page_size
+ items = query.order_by(desc(Information.created_at)).offset(offset).limit(page_size).all()
+ return {"data": items, "pagination": {"page": page, "limit": page_size, "total": total}}
diff --git a/config/VERSION b/config/VERSION
index d659080..532db09 100644
--- a/config/VERSION
+++ b/config/VERSION
@@ -1 +1 @@
-VERSION=1.2.59
+VERSION=1.2.50
diff --git a/frontend/index.html b/frontend/index.html
index 2af0426..6525875 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -4,7 +4,7 @@
-
甲辰收藏 v1.2.53
+ 甲辰收藏 v1.2.50
diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx
index dc0262b..1a044ca 100644
--- a/frontend/src/pages/Home.jsx
+++ b/frontend/src/pages/Home.jsx
@@ -5,6 +5,8 @@ export default function Home() {
const [user, setUser] = useState(null)
const [stats, setStats] = useState({ totalCount: 0, totalCost: 0, totalRevenue: 0, expectedProfit: 0, totalProfit: 0, gradedCount: 0 })
const [recentCollections, setRecentCollections] = useState([])
+ const [yichensStats, setYichensStats] = useState({ total: 0, deals: 0, wants: 0, dragons: 0, horses: 0, tianma: 0 })
+ const [recentPosts, setRecentPosts] = useState([])
const currentPath = window.location.hash.slice(1) || '/'
useEffect(() => {
@@ -54,6 +56,18 @@ export default function Home() {
}
}, [])
+ // 获取一尘看板数据
+ useEffect(() => {
+ fetch('/api/yichens/stats/today').then(res => res.json()).then(data => {
+ setYichensStats(data || {})
+ }).catch(() => {})
+
+ // 获取最新一尘帖子
+ fetch('/api/yichens/posts?limit=10&offset=0').then(res => res.json()).then(data => {
+ setRecentPosts(Array.isArray(data) ? data : [])
+ }).catch(() => {})
+ }, [])
+
// 检查是否为管理员
const isAdmin = user && user.role === 'admin'
@@ -96,7 +110,7 @@ export default function Home() {
backdropFilter: 'blur(10px)'
}}>
-

+
{user?.username || '用户'}
欢迎回来 👋
@@ -175,11 +189,42 @@ export default function Home() {
- {/* 最近藏品 */}
+ {/* 一尘今日数据 */}
+
+
📊 一尘今日数据
+
+
+
{yichensStats.total || 0}
+
总帖子
+
+
+
{yichensStats.deals || 0}
+
出售
+
+
+
{yichensStats.wants || 0}
+
求购
+
+
+
{yichensStats.dragons || 0}
+
龙钞
+
+
+
{yichensStats.horses || 0}
+
马钞
+
+
+
{yichensStats.tianma || 0}
+
天马
+
+
+
+
+ {/* 最新一尘发帖 */}
-
最近藏品
-
window.location.hash = '#/list'} style={{ color: '#3b82f6', fontSize: '12px', cursor: 'pointer' }}>查看全部 →
+
📝 最新一尘发帖
+
window.location.hash = '#/news'} style={{ color: '#3b82f6', fontSize: '12px', cursor: 'pointer' }}>查看全部 →
- {recentCollections.length === 0 ? (
-
暂无藏品
+ {recentPosts.length === 0 ? (
+
暂无帖子
) : (
- recentCollections.map((item, idx) => (
-
window.location.hash = '#/detail?id=' + item.id} style={{
+ recentPosts.map((item, idx) => (
+
window.location.hash = '#/news'} style={{
padding: '12px 16px',
- borderBottom: idx < recentCollections.length - 1 ? '1px solid rgba(255,255,255,0.05)' : 'none',
+ borderBottom: idx < recentPosts.length - 1 ? '1px solid rgba(255,255,255,0.05)' : 'none',
cursor: 'pointer',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
}}>
-
-
{item.code || '-'} {item.prefixSerial || ''}
-
{item.version || '-'} · {item.status === 'sold' ? '已售' : item.status === 'in_collection' ? '收藏中' : item.status}
+
+
{item.title || '无标题'}
+
{item.category || '-'} · {item.author_username || '未知'} · {item.post_time?.substring(0, 16) || ''}
-
- {item.costPrice ? '¥' + item.costPrice : '-'}
+
+ {item.post_type === 'deal' ? '出售' : item.post_type === 'want' ? '求购' : '其他'}
))
diff --git a/frontend/src/pages/Info.jsx b/frontend/src/pages/Info.jsx
index 390bdb8..17c7baf 100644
--- a/frontend/src/pages/Info.jsx
+++ b/frontend/src/pages/Info.jsx
@@ -672,6 +672,9 @@ export default function Info() {
)}
-
+
)
}
+
+
+
diff --git a/frontend/src/pages/News.jsx b/frontend/src/pages/News.jsx
index 04cb53f..b316cc6 100644
--- a/frontend/src/pages/News.jsx
+++ b/frontend/src/pages/News.jsx
@@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react'
+import YichensBoard from './YichensBoard'
// 本地获取用户手机号 - 添加异常处理
const getUserPhone = () => {
@@ -22,7 +23,7 @@ const getStoredUserId = () => {
// 资讯页面 - 展示寻配号和行情信息(所有人可见)
export default function News() {
- const [activeTab, setActiveTab] = useState(localStorage.getItem('news_activeTab') || 'seek')
+ const [activeTab, setActiveTab] = useState(localStorage.getItem('news_activeTab') || 'yichen')
const [showSeekPublish, setShowSeekPublish] = useState(false)
const [showMySeeks, setShowMySeeks] = useState(false) // 我的寻号
const [showContactId, setShowContactId] = useState(null) // 显示联系方式的寻号ID
@@ -32,6 +33,8 @@ export default function News() {
const [matchedStatus, setMatchedStatus] = useState({}) // 存储各寻号的匹配状态
const [showMatchList, setShowMatchList] = useState(false)
const [matchCollections, setMatchCollections] = useState([])
+ const [networkMatchCollections, setNetworkMatchCollections] = useState([])
+ const [showNetworkMatchList, setShowNetworkMatchList] = useState(false)
const [customModal, setCustomModal] = useState({show: false, title: '', content: ''})
const [seekForm, setSeekForm] = useState({
edition: '龙钞', type: '', category: '寻号', price: '', matchType: '模糊', features: '', content: '', title: '', contact: getUserPhone() || ''
@@ -40,6 +43,8 @@ export default function News() {
const [viewMode, setViewMode] = useState('all')
const [expandedItems, setExpandedItems] = useState({}) // 展开状态
const [loading, setLoading] = useState(false)
+ const [currentPage, setCurrentPage] = useState(1)
+ const [totalPages, setTotalPages] = useState(1)
const API_BASE = localStorage.getItem('API_BASE') || ''
const currentUser = localStorage.getItem('token') ? { id: 'logged_in' } : null
@@ -69,10 +74,13 @@ export default function News() {
// 寻配号对所有人公开,无需登录即可查看
const token = localStorage.getItem('token')
// 根据tab获取不同类型的数据
- const type = activeTab === 'seek' ? 'seek' : 'deal'
+ const type = activeTab === 'seek' ? 'seek' : activeTab === 'deal' ? 'deal' : 'yichen'
// 始终传递token,以便获取准确的matched_count
const headers = token ? { Authorization: `Bearer ${token}` } : {}
- const res = await fetch(`${API_BASE}/api/information/list?info_type=${type}`, { headers })
+ const res = await fetch(`${API_BASE}/api/information/list?info_type=${type}&page=${currentPage}&page_size=50`, { headers })
+ // 从响应头获取总页数
+ const total = res.headers.get('X-Total-Pages') || res.headers.get('x-total-pages')
+ if (total) setTotalPages(parseInt(total))
// 检查响应状态
if (!res.ok) {
console.error('获取资讯列表失败:', res.status)
@@ -146,10 +154,11 @@ export default function News() {
const token = localStorage.getItem('token')
if (!token) { alert('请先登录'); return }
try {
+ const phone = getUserPhone()
const res = await fetch(`${API_BASE}/api/information/seek/match-confirm`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
- body: JSON.stringify({ info_id: infoId })
+ body: JSON.stringify({ info_id: infoId, contact: phone || '用户已同意' })
})
const data = await res.json()
if (data.message === '匹配成功,已通知发布者') {
@@ -187,7 +196,7 @@ export default function News() {
console.log('Matched user response:', res.status)
const data = await res.json()
console.log('Matched user data:', data)
- if (data.user_name) setCustomModal({show: true, title: '匹配者信息', content: `用户名: ${data.user_name}\n联系方式: ${data.matched_contact || '未提供'}`})
+ if (data.user_name) setCustomModal({show: true, title: '匹配者信息', content: `用户名: ${data.user_name}\n手机号: ${data.phone || '未提供'}\n\n免责声明及风险提示:所有用户信息仅作参考,交易请走正规平台,如产生经济损失与本站无关,后果自负。`})
else if (data.detail) alert(data.detail)
} catch (e) { console.error(e) }
}
@@ -200,7 +209,7 @@ export default function News() {
console.log('Publisher response:', res.status)
const data = await res.json()
console.log('Publisher data:', data)
- if (data.user_name) setCustomModal({show: true, title: '发布者信息', content: `用户名: ${data.user_name}\n联系方式: ${data.contact || '未提供'}`})
+ if (data.user_name) setCustomModal({show: true, title: '发布者信息', content: `用户名: ${data.user_name}\n手机号: ${data.phone || '未提供'}\n\n免责声明及风险提示:所有用户信息仅作参考,交易请走正规平台,如产生经济损失与本站无关,后果自负。`})
else if (data.detail) alert(data.detail)
} catch (e) { console.error(e) }
}
@@ -223,6 +232,20 @@ export default function News() {
}
}
+ // 获取网络数据匹配列表
+ const fetchNetworkMatchCollections = async (infoId) => {
+ try {
+ const res = await fetch(`${API_BASE}/api/information/seek/network-match/${infoId}`)
+ const data = await res.json()
+ console.log('网络数据匹配结果:', data)
+ setNetworkMatchCollections(data.collections || [])
+ setShowNetworkMatchList(true)
+ } catch (e) {
+ console.error('获取网络匹配藏品失败:', e)
+ alert('获取网络匹配藏品失败: ' + e.message)
+ }
+ }
+
// 获取当前用户ID
const currentUserId = getStoredUserId()
@@ -315,7 +338,8 @@ export default function News() {
// Tab切换
const tabs = [
{ key: 'seek', label: '🔍 寻配号' },
- { key: 'deal', label: '💰 成交行情' }
+ { key: 'deal', label: '💰 成交行情' },
+ { key: 'yichen', label: '📊 一尘看板' }
]
const formatDate = (dateStr) => {
@@ -387,7 +411,7 @@ export default function News() {
readOnly={isFixed}
onChange={(e) => {
if (i < 2) return
- const val = e.target.value.toUpperCase().replace(/[^0-9XABCFG]/g, '')
+ const val = e.target.value.toUpperCase().replace(/[^0-9XABCDEFG]/g, '')
const newFeatures = (seekForm.features || '').split('')
while (newFeatures.length < 8) newFeatures.push('')
newFeatures[i - 2] = val
@@ -435,7 +459,7 @@ export default function News() {
)}
- {activeTab === 'seek' ? '🔍 寻配号信息' : '💰 成交行情信息'}
+ {activeTab === 'seek' ? '🔍 寻配号信息' : activeTab === 'deal' ? '💰 成交行情信息' : '📊 一尘看板'}
{activeTab === 'seek' && (
@@ -450,11 +474,11 @@ export default function News() {
加载中...
) : infoList.length === 0 ? (
- 暂无{activeTab === 'seek' ? '寻配号' : '成交行情'}信息
+ 暂无{activeTab === 'seek' ? '寻配号' : activeTab === 'deal' ? '成交行情' : '一尘看板'}信息
) : (
- {infoList.map(item => {
+ {activeTab === 'yichen' ? : infoList.map(item => {
// 解析正文中的号码特征和联系方式
const content = item.content || ''
const featuresMatch = content.match(/号码特征[:\s]*(.+?)(?:\n|$)/)
@@ -472,7 +496,7 @@ export default function News() {
{/* 创建日期 + 用户名 */}
- 📅 {formatDate(item.created_at)} | 👤 {item.user_name || '匿名用户'}
+ 📅 {formatDate(item.created_at)} | 👤 {(item.content && item.content.match(/发布者: (.+)/)?.[1]) || item.user_name || '匿名用户'}
{/* 号码特征 */}
{features && (
@@ -521,12 +545,20 @@ export default function News() {
{/* 配号结果 - 仅寻配号显示 */}
{activeTab === 'seek' && (
- fetchMatchCollections(item.id)}
>
- 配号结果: {item.matched_count || 0}条藏品匹配成功
+ 自有{item.matched_count || 0}条藏品匹配成功
+ {item.network_matched_count !== undefined && (
+ fetchNetworkMatchCollections(item.id)}
+ >
+ 网络数据{item.network_matched_count}条匹配成功
+
+ )}
)}
{/* 正文 - 默认收起,点击展开 */}
@@ -613,23 +645,24 @@ export default function News() {
)}
+ {/* 网络数据匹配藏品列表弹窗 */}
+ {showNetworkMatchList && (
+
+
+
+
匹配藏品清单(网络数据)
+
+
+ {networkMatchCollections.length === 0 ? (
+
暂无匹配藏品
+ ) : (
+
+ {networkMatchCollections.map(c => (
+
{
+ if (c.post_url) {
+ window.open(c.post_url, '_blank')
+ }
+ setShowNetworkMatchList(false)
+ }}
+ >
+
+ 名称: {c.name || '-'}
+
+
+ 冠字号: {c.crown_code}
+
+ {c.price && (
+
+ 价格: ¥{c.price}
+
+ )}
+
+ 点击查看原帖 →
+
+
+ ))}
+
+ )}
+
+
+ )}
+
+ {/* 分页组件 */}
+ {totalPages > 1 && (
+
+
+
+ 第 {currentPage} / {totalPages} 页
+
+
+
+ )}
+
{/* 我的寻号弹窗 */}
{showMySeeks && (