Compare commits

..

4 Commits

Author SHA1 Message Date
socool 0b56cd7891 v0.0.7 - 版本更新:代码清理完成
- VERSION.json: 0.0.6 → 0.0.7
- CHANGELOG.md: 更新v0.0.7更新记录

主要更新:
1. coolbot_matcher.py - 一尘匹配工具模块
2. seek.py - 优化列表加载,添加缺失端点
3. information.py - 注释废弃端点
4. News.jsx - API迁移到seek
2026-04-24 11:23:18 +08:00
socool 7100f2d40e 清理:注释information.py中废弃的seek/deal重复端点
已废弃并注释的端点(统一使用 /api/seek/* 或 /api/deal/*):
- /information/seek/match → /api/seek/my-match
- /information/seek/network-match/{id} → /api/seek/network-match/{id}
- /information/my-seeks → /api/seek/list
- /information/seek/match-confirm → /api/seek/match-confirm
- /information/seek/matched-user/{id} → /api/seek/matched-user/{id}
- /information/seek/publisher/{id} → /api/seek/publisher/{id}
- /information/seek/stats → /api/seek/stats
- /information/deal/stats → /api/deal/stats

注意:评论相关端点保留(comment, comments),表为空但代码存在
2026-04-24 11:21:41 +08:00
socool 41b3353613 优化:列表接口移除网络匹配实时计算,提升加载速度
- seek.py /list 端点不再实时计算 network_matched_count
- 网络匹配仅在点击时通过 /network-match/{id} 单独查询
2026-04-24 11:20:17 +08:00
socool e6a0b4fb34 清理废弃代码:(1)创建coolbot_matcher.py工具模块 (2)更新seek.py添加缺失端点并导入新工具 (3)更新News.jsx迁移API到seek.py
Changes:
- backend/app/utils/coolbot_matcher.py: 新建一尘数据库匹配工具模块
- backend/app/routers/seek.py: 更新导入,添加match-confirm/matched-user/publisher端点
- frontend/src/pages/News.jsx: API调用从information迁移到seek

Note: Skill文档已单独更新到47.96.181.36
2026-04-24 11:14:56 +08:00
6 changed files with 686 additions and 353 deletions

View File

@ -636,183 +636,183 @@ def delete_information(
# 寻配号 - 自动匹配推荐藏品 # 寻配号 - 自动匹配推荐藏品
@router.get("/seek/match") # DEPRECATED (use /api/seek/*): @router.get("/seek/match")
def get_seek_match( # DEPRECATED: def get_seek_match(
info_id: str, # DEPRECATED: info_id: str,
current_user: Optional[User] = Depends(get_current_user), # DEPRECATED: current_user: Optional[User] = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取符合条件的我的藏品推荐""" # DEPRECATED: """获取符合条件的我的藏品推荐"""
if not current_user: # DEPRECATED: if not current_user:
raise HTTPException(status_code=401, detail="请先登录") # DEPRECATED: raise HTTPException(status_code=401, detail="请先登录")
# DEPRECATED:
# 先查 information 表 # 先查 information 表
info = db.query(Information).filter( # DEPRECATED: info = db.query(Information).filter(
Information.id == info_id, # DEPRECATED: Information.id == info_id,
Information.info_type == "seek" # DEPRECATED: Information.info_type == "seek"
).first() # DEPRECATED: ).first()
# DEPRECATED:
# 如果 information 表没有,尝试 seek_info 表 # 如果 information 表没有,尝试 seek_info 表
if not info: # DEPRECATED: if not info:
from app.models.seek_info import SeekInfo # DEPRECATED: from app.models.seek_info import SeekInfo
info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first() # DEPRECATED: info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first()
# DEPRECATED:
if not info: # DEPRECATED: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") # DEPRECATED: raise HTTPException(status_code=404, detail="寻配号信息不存在")
# DEPRECATED:
# 更新用户配号(寻号)次数 # 更新用户配号(寻号)次数
current_user.f99_96_search_count = (current_user.f99_96_search_count or 0) + 1 # DEPRECATED: current_user.f99_96_search_count = (current_user.f99_96_search_count or 0) + 1
db.commit() # DEPRECATED: db.commit()
# DEPRECATED:
# 获取用户所有藏品 # 获取用户所有藏品
collections = db.query(Collection).filter( # DEPRECATED: collections = db.query(Collection).filter(
Collection.f99_91_user_id == current_user.f99_90_id, # DEPRECATED: Collection.f99_91_user_id == current_user.f99_90_id,
Collection.f01_04_status == "in_collection" # DEPRECATED: Collection.f01_04_status == "in_collection"
).all() # DEPRECATED: ).all()
# DEPRECATED:
# 去掉版别筛选,因为藏品分类和发布需求的版别不同 # 去掉版别筛选,因为藏品分类和发布需求的版别不同
# if info.expect_category: # if info.expect_category:
# collections = [c for c in collections if c.f01_03_category == info.expect_category] # collections = [c for c in collections if c.f01_03_category == info.expect_category]
# DEPRECATED:
# 按号码特征模式匹配 # 按号码特征模式匹配
matched = [] # DEPRECATED: matched = []
if info.expect_number and len(info.expect_number) == 10: # DEPRECATED: if info.expect_number and len(info.expect_number) == 10:
pattern = info.expect_number[2:] # 后8位 # DEPRECATED: pattern = info.expect_number[2:] # 后8位
for c in collections: # DEPRECATED: for c in collections:
number = c.f02_10_prefix_serial or '' # DEPRECATED: number = c.f02_10_prefix_serial or ''
# 去掉J0前缀后取前8位 # 去掉J0前缀后取前8位
if len(number) >= 10 and number.startswith('J0'): # DEPRECATED: if len(number) >= 10 and number.startswith('J0'):
col_pattern = number[2:10] # 取J0后面的8位 # DEPRECATED: col_pattern = number[2:10] # 取J0后面的8位
if match_pattern(col_pattern, pattern): # DEPRECATED: if match_pattern(col_pattern, pattern):
matched.append(c) # DEPRECATED: matched.append(c)
elif len(number) >= 8: # DEPRECATED: elif len(number) >= 8:
col_pattern = number[:8] # 取前8位 # DEPRECATED: col_pattern = number[:8] # 取前8位
if match_pattern(col_pattern, pattern): # DEPRECATED: if match_pattern(col_pattern, pattern):
matched.append(c) # DEPRECATED: matched.append(c)
else: # DEPRECATED: else:
matched = collections # DEPRECATED: matched = collections
# DEPRECATED:
return { # DEPRECATED: return {
"info_id": info_id, # DEPRECATED: "info_id": info_id,
"matched_count": len(matched), # DEPRECATED: "matched_count": len(matched),
"collections": [ # DEPRECATED: "collections": [
{ # DEPRECATED: {
"id": c.f99_90_id, # DEPRECATED: "id": c.f99_90_id,
"code": c.f01_02_code or '', # DEPRECATED: "code": c.f01_02_code or '',
"name": c.f01_01_name, # DEPRECATED: "name": c.f01_01_name,
"number": c.f02_10_prefix_serial, # DEPRECATED: "number": c.f02_10_prefix_serial,
"status": c.f01_04_status, # DEPRECATED: "status": c.f01_04_status,
"category": c.f01_03_category, # DEPRECATED: "category": c.f01_03_category,
"version": c.f02_11_version, # DEPRECATED: "version": c.f02_11_version,
"packaging": c.f02_12_packaging, # DEPRECATED: "packaging": c.f02_12_packaging,
"cost_price": c.f05_40_cost_price, # DEPRECATED: "cost_price": c.f05_40_cost_price,
} # DEPRECATED: }
for c in matched # DEPRECATED: for c in matched
], # DEPRECATED: ],
"network_matched_count": match_collections_count_from_coolbot(info.expect_number) if info.expect_number else 0, # DEPRECATED: "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 [] # DEPRECATED: "network_collections": match_collections_list_from_coolbot(info.expect_number, limit=20) if info.expect_number else []
} # DEPRECATED: }
# DEPRECATED:
# DEPRECATED:
# 获取网络数据匹配列表 # 获取网络数据匹配列表
@router.get("/seek/network-match/{info_id}") # DEPRECATED (use /api/seek/*): @router.get("/seek/network-match/{info_id}")
def get_network_match( # DEPRECATED: def get_network_match(
info_id: str, # DEPRECATED: info_id: str,
limit: int = Query(20, ge=1, le=100), # DEPRECATED: limit: int = Query(20, ge=1, le=100),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取一尘数据库中匹配的藏品列表""" # DEPRECATED: """获取一尘数据库中匹配的藏品列表"""
info = db.query(Information).filter( # DEPRECATED: info = db.query(Information).filter(
Information.id == info_id, # DEPRECATED: Information.id == info_id,
Information.info_type == "seek" # DEPRECATED: Information.info_type == "seek"
).first() # DEPRECATED: ).first()
# DEPRECATED:
if not info: # DEPRECATED: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") # DEPRECATED: raise HTTPException(status_code=404, detail="寻配号信息不存在")
# DEPRECATED:
if not info.expect_number: # DEPRECATED: if not info.expect_number:
return {"matched_count": 0, "collections": []} # DEPRECATED: return {"matched_count": 0, "collections": []}
# DEPRECATED:
matched = match_collections_list_from_coolbot(info.expect_number, limit=limit) # DEPRECATED: matched = match_collections_list_from_coolbot(info.expect_number, limit=limit)
# DEPRECATED:
return { # DEPRECATED: return {
"matched_count": len(matched), # DEPRECATED: "matched_count": len(matched),
"collections": matched # DEPRECATED: "collections": matched
} # DEPRECATED: }
# DEPRECATED:
# DEPRECATED:
# 我的寻号列表 # 我的寻号列表
@router.get("/my-seeks") # DEPRECATED (use /api/seek/*): @router.get("/my-seeks")
def get_my_seeks( # DEPRECATED: def get_my_seeks(
current_user: Optional[User] = Depends(get_current_user), # DEPRECATED: current_user: Optional[User] = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取当前用户发布的所有寻号信息""" # DEPRECATED: """获取当前用户发布的所有寻号信息"""
if not current_user: # DEPRECATED: if not current_user:
raise HTTPException(status_code=401, detail="请先登录") # DEPRECATED: raise HTTPException(status_code=401, detail="请先登录")
# DEPRECATED:
items = db.query(Information).filter( # DEPRECATED: items = db.query(Information).filter(
Information.user_id == current_user.f99_90_id, # DEPRECATED: Information.user_id == current_user.f99_90_id,
Information.info_type == "seek", # DEPRECATED: Information.info_type == "seek",
Information.status == "active" # DEPRECATED: Information.status == "active"
).order_by(Information.created_at.desc()).all() # DEPRECATED: ).order_by(Information.created_at.desc()).all()
# DEPRECATED:
result = [] # DEPRECATED: result = []
for item in items: # DEPRECATED: for item in items:
# 计算匹配数量 # 计算匹配数量
matched_count = 0 # DEPRECATED: matched_count = 0
if item.expect_number: # DEPRECATED: if item.expect_number:
matched_count = match_collections_count(db, current_user.f99_90_id, item.expect_number) # DEPRECATED: matched_count = match_collections_count(db, current_user.f99_90_id, item.expect_number)
# DEPRECATED:
result.append(InformationResponse( # DEPRECATED: result.append(InformationResponse(
id=item.id, # DEPRECATED: id=item.id,
user_id=item.user_id, # DEPRECATED: user_id=item.user_id,
info_type=item.info_type, # DEPRECATED: info_type=item.info_type,
title=item.title, # DEPRECATED: title=item.title,
content=item.content, # DEPRECATED: content=item.content,
collection_id=item.collection_id, # DEPRECATED: collection_id=item.collection_id,
expect_category=item.expect_category, # DEPRECATED: expect_category=item.expect_category,
expect_version=item.expect_version, # DEPRECATED: expect_version=item.expect_version,
expect_packaging=item.expect_packaging, # DEPRECATED: expect_packaging=item.expect_packaging,
expect_number=item.expect_number, # DEPRECATED: expect_number=item.expect_number,
expect_price_min=item.expect_price_min, # DEPRECATED: expect_price_min=item.expect_price_min,
expect_price_max=item.expect_price_max, # DEPRECATED: expect_price_max=item.expect_price_max,
deal_price=item.deal_price, # DEPRECATED: deal_price=item.deal_price,
deal_date=item.deal_date, # DEPRECATED: deal_date=item.deal_date,
status=item.status, # DEPRECATED: status=item.status,
is_matched=item.is_matched, # DEPRECATED: is_matched=item.is_matched,
matched_user_id=item.matched_user_id, # DEPRECATED: matched_user_id=item.matched_user_id,
matched_contact=item.matched_contact, # DEPRECATED: matched_contact=item.matched_contact,
view_count=item.view_count, # DEPRECATED: view_count=item.view_count,
contact_count=item.contact_count, # DEPRECATED: contact_count=item.contact_count,
created_at=item.created_at, # DEPRECATED: created_at=item.created_at,
user_name=item.user.f01_01_name if item.user else None, # DEPRECATED: user_name=item.user.f01_01_name if item.user else None,
user_avatar=item.user.avatar if item.user else None, # DEPRECATED: user_avatar=item.user.avatar if item.user else None,
collection_name=item.collection.f01_01_name if item.collection else None, # DEPRECATED: collection_name=item.collection.f01_01_name if item.collection else None,
collection_category=item.collection.f01_03_category if item.collection else None, # DEPRECATED: collection_category=item.collection.f01_03_category if item.collection else None,
collection_version=item.collection.f02_11_version if item.collection else None, # DEPRECATED: 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, # DEPRECATED: collection_number=item.collection.f02_10_prefix_serial if item.collection else None,
matched_count=matched_count, # DEPRECATED: 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, # DEPRECATED: network_matched_count=match_collections_count_from_coolbot(item.expect_number) if item.info_type == 'seek' and item.expect_number else 0,
)) # DEPRECATED: ))
# DEPRECATED:
# 获取总数并设置响应头 # 获取总数并设置响应头
from fastapi import Response # DEPRECATED: from fastapi import Response
total_query = db.query(Information).filter(Information.status == status) # DEPRECATED: total_query = db.query(Information).filter(Information.status == status)
if info_type: # DEPRECATED: if info_type:
total_query = total_query.filter(Information.info_type == info_type) # DEPRECATED: total_query = total_query.filter(Information.info_type == info_type)
total_count = total_query.count() # DEPRECATED: total_count = total_query.count()
total_pages = (total_count + page_size - 1) // page_size # DEPRECATED: total_pages = (total_count + page_size - 1) // page_size
# DEPRECATED:
# 设置响应头 # 设置响应头
response.headers['X-Total-Pages'] = str(total_pages) # DEPRECATED: response.headers['X-Total-Pages'] = str(total_pages)
response.headers['X-Total-Count'] = str(total_count) # DEPRECATED: response.headers['X-Total-Count'] = str(total_count)
# DEPRECATED:
return result # DEPRECATED: return result
# DEPRECATED:
# DEPRECATED:
# 成交数据统计 # 成交数据统计
@router.get("/deal/stats") # DEPRECATED (use /api/deal/stats): @router.get("/deal/stats")
def get_deal_stats( def get_deal_stats(
days: int = Query(7, ge=1, le=90, description="统计天数"), days: int = Query(7, ge=1, le=90, description="统计天数"),
db: Session = Depends(get_db) db: Session = Depends(get_db)
@ -959,49 +959,49 @@ class MatchSeekRequest(BaseModel):
contact: Optional[str] = None contact: Optional[str] = None
@router.post("/seek/match-confirm") # DEPRECATED (use /api/seek/*): @router.post("/seek/match-confirm")
def match_seek( # DEPRECATED: def match_seek(
request: MatchSeekRequest, # DEPRECATED: request: MatchSeekRequest,
current_user: User = Depends(get_current_user), # DEPRECATED: current_user: User = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""确认匹配寻号 - 用户愿意交换联系方式给发布者""" # DEPRECATED: """确认匹配寻号 - 用户愿意交换联系方式给发布者"""
info = db.query(Information).filter( # DEPRECATED: info = db.query(Information).filter(
Information.id == request.info_id, # DEPRECATED: Information.id == request.info_id,
Information.info_type == "seek", # DEPRECATED: Information.info_type == "seek",
Information.status == "active" # DEPRECATED: Information.status == "active"
).first() # DEPRECATED: ).first()
# DEPRECATED:
if not info: # DEPRECATED: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") # DEPRECATED: raise HTTPException(status_code=404, detail="寻配号信息不存在")
# DEPRECATED:
# 检查是否已被匹配(一个寻号只能被一个用户匹配) # 检查是否已被匹配(一个寻号只能被一个用户匹配)
if info.is_matched == "matched": # DEPRECATED: if info.is_matched == "matched":
raise HTTPException(status_code=400, detail="该寻号已被其他用户匹配") # DEPRECATED: raise HTTPException(status_code=400, detail="该寻号已被其他用户匹配")
# DEPRECATED:
# 更新匹配状态 # 更新匹配状态
info.is_matched = "matched" # DEPRECATED: info.is_matched = "matched"
info.matched_user_id = current_user.f99_90_id # DEPRECATED: info.matched_user_id = current_user.f99_90_id
# 保存匹配者的联系方式 # 保存匹配者的联系方式
info.matched_contact = request.contact or '' # DEPRECATED: info.matched_contact = request.contact or ''
# DEPRECATED:
# 更新发布寻号者的内容,显示有藏品被匹配 # 更新发布寻号者的内容,显示有藏品被匹配
original_content = info.content or "" # DEPRECATED: original_content = info.content or ""
# 添加匹配信息藏品被XX藏友匹配联系方式为xxx # 添加匹配信息藏品被XX藏友匹配联系方式为xxx
match_info = f"\n藏品被{current_user.f01_01_name}匹配成功!联系方式:{request.collection_id or '已交换'}" # DEPRECATED: match_info = f"\n藏品被{current_user.f01_01_name}匹配成功!联系方式:{request.collection_id or '已交换'}"
info.content = original_content + match_info # DEPRECATED: info.content = original_content + match_info
# DEPRECATED:
db.commit() # DEPRECATED: db.commit()
# DEPRECATED:
return {"message": "匹配成功,已通知发布者", "is_matched": "matched"} # DEPRECATED: return {"message": "匹配成功,已通知发布者", "is_matched": "matched"}
# DEPRECATED:
# DEPRECATED:
# ============ 添加留言 ============ # ============ 添加留言 ============
class CommentRequest(BaseModel): # DEPRECATED: class CommentRequest(BaseModel):
information_id: str # DEPRECATED: information_id: str
content: str # DEPRECATED: content: str
# DEPRECATED:
# DEPRECATED:
@router.post("/comment") @router.post("/comment")
def add_comment( def add_comment(
request: CommentRequest, request: CommentRequest,
@ -1063,84 +1063,84 @@ def get_comments(
# ============ 获取匹配者信息 ============ # ============ 获取匹配者信息 ============
@router.get("/seek/matched-user/{info_id}") # DEPRECATED (use /api/seek/*): @router.get("/seek/matched-user/{info_id}")
def get_matched_user( # DEPRECATED: def get_matched_user(
info_id: str, # DEPRECATED: info_id: str,
current_user: User = Depends(get_current_user), # DEPRECATED: current_user: User = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取寻号的匹配者信息(仅发布者可见)""" # DEPRECATED: """获取寻号的匹配者信息(仅发布者可见)"""
info = db.query(Information).filter( # DEPRECATED: info = db.query(Information).filter(
Information.id == info_id, # DEPRECATED: Information.id == info_id,
Information.info_type == "seek" # DEPRECATED: Information.info_type == "seek"
).first() # DEPRECATED: ).first()
# DEPRECATED:
if not info: # DEPRECATED: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") # DEPRECATED: raise HTTPException(status_code=404, detail="寻配号信息不存在")
# DEPRECATED:
# 只有发布者可以看到匹配者信息 # 只有发布者可以看到匹配者信息
if info.user_id != current_user.f99_90_id: # DEPRECATED: if info.user_id != current_user.f99_90_id:
raise HTTPException(status_code=403, detail="无权访问") # DEPRECATED: raise HTTPException(status_code=403, detail="无权访问")
# DEPRECATED:
if not info.matched_user_id: # DEPRECATED: if not info.matched_user_id:
return {"message": "暂无匹配者"} # DEPRECATED: return {"message": "暂无匹配者"}
# DEPRECATED:
# 获取匹配者信息 # 获取匹配者信息
matched_user = db.query(User).filter(User.f99_90_id == info.matched_user_id).first() # DEPRECATED: matched_user = db.query(User).filter(User.f99_90_id == info.matched_user_id).first()
if not matched_user: # DEPRECATED: if not matched_user:
return {"message": "匹配者不存在"} # DEPRECATED: return {"message": "匹配者不存在"}
# DEPRECATED:
return { # DEPRECATED: return {
"matched_user_id": info.matched_user_id, # DEPRECATED: "matched_user_id": info.matched_user_id,
"user_name": matched_user.f01_01_name, # DEPRECATED: "user_name": matched_user.f01_01_name,
"phone": matched_user.phone, # DEPRECATED: "phone": matched_user.phone,
"matched_contact": info.matched_contact, # DEPRECATED: "matched_contact": info.matched_contact,
"matched_at": info.updated_at.isoformat() if info.updated_at else None # DEPRECATED: "matched_at": info.updated_at.isoformat() if info.updated_at else None
} # DEPRECATED: }
# DEPRECATED:
# DEPRECATED:
# ============ 获取发布者信息 ============ # ============ 获取发布者信息 ============
@router.get("/seek/publisher/{info_id}") # DEPRECATED (use /api/seek/*): @router.get("/seek/publisher/{info_id}")
def get_publisher_info( # DEPRECATED: def get_publisher_info(
info_id: str, # DEPRECATED: info_id: str,
current_user: User = Depends(get_current_user), # DEPRECATED: current_user: User = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取寻号的发布者信息(仅匹配者可见)""" # DEPRECATED: """获取寻号的发布者信息(仅匹配者可见)"""
info = db.query(Information).filter( # DEPRECATED: info = db.query(Information).filter(
Information.id == info_id, # DEPRECATED: Information.id == info_id,
Information.info_type == "seek" # DEPRECATED: Information.info_type == "seek"
).first() # DEPRECATED: ).first()
# DEPRECATED:
if not info: # DEPRECATED: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") # DEPRECATED: raise HTTPException(status_code=404, detail="寻配号信息不存在")
# DEPRECATED:
# 只有匹配者可以看到发布者信息 # 只有匹配者可以看到发布者信息
if not info.matched_user_id or info.matched_user_id != current_user.f99_90_id: # DEPRECATED: if not info.matched_user_id or info.matched_user_id != current_user.f99_90_id:
raise HTTPException(status_code=403, detail="无权访问") # DEPRECATED: raise HTTPException(status_code=403, detail="无权访问")
# DEPRECATED:
# 获取发布者信息 # 获取发布者信息
publisher = db.query(User).filter(User.f99_90_id == info.user_id).first() # DEPRECATED: publisher = db.query(User).filter(User.f99_90_id == info.user_id).first()
if not publisher: # DEPRECATED: if not publisher:
return {"message": "发布者不存在"} # DEPRECATED: return {"message": "发布者不存在"}
# DEPRECATED:
# 从content中解析联系方式 # 从content中解析联系方式
contact = '' # DEPRECATED: contact = ''
if info.content: # DEPRECATED: if info.content:
import re # DEPRECATED: import re
match = re.search(r'联系方式[:\s]*(.+?)(?:\n|$)', info.content) # DEPRECATED: match = re.search(r'联系方式[:\s]*(.+?)(?:\n|$)', info.content)
if match: # DEPRECATED: if match:
contact = match.group(1).strip() # DEPRECATED: contact = match.group(1).strip()
# DEPRECATED:
return { # DEPRECATED: return {
"user_id": info.user_id, # DEPRECATED: "user_id": info.user_id,
"user_name": publisher.f01_01_name, # DEPRECATED: "user_name": publisher.f01_01_name,
"phone": publisher.phone, # DEPRECATED: "phone": publisher.phone,
"contact": contact, # DEPRECATED: "contact": contact,
"created_at": info.created_at.isoformat() if info.created_at else None # DEPRECATED: "created_at": info.created_at.isoformat() if info.created_at else None
} # DEPRECATED: }
# DEPRECATED:
# DEPRECATED:
@router.get("/yichen-posts") @router.get("/yichen-posts")
def get_yichen_posts(category: str = None, search: str = None, page: int = 1, page_size: int = 20): def get_yichen_posts(category: str = None, search: str = None, page: int = 1, page_size: int = 20):
from app.models.models import Information from app.models.models import Information
@ -1156,59 +1156,59 @@ def get_yichen_posts(category: str = None, search: str = None, page: int = 1, pa
return {"data": items, "pagination": {"page": page, "limit": page_size, "total": total}} return {"data": items, "pagination": {"page": page, "limit": page_size, "total": total}}
@router.get("/seek/stats") # DEPRECATED (use /api/seek/*): @router.get("/seek/stats")
def get_seek_stats( # DEPRECATED: def get_seek_stats(
current_user: User = Depends(get_current_user), # DEPRECATED: current_user: User = Depends(get_current_user),
db: Session = Depends(get_db) # DEPRECATED: db: Session = Depends(get_db)
): # DEPRECATED: ):
"""获取寻配号统计数据""" # DEPRECATED: """获取寻配号统计数据"""
# 寻号需求数seek类型且expect_number不为空的总数 # 寻号需求数seek类型且expect_number不为空的总数
seek_count = db.query(Information).filter( # DEPRECATED: seek_count = db.query(Information).filter(
Information.info_type == 'seek', # DEPRECATED: Information.info_type == 'seek',
Information.expect_number.isnot(None), # DEPRECATED: Information.expect_number.isnot(None),
Information.expect_number != '' # DEPRECATED: Information.expect_number != ''
).count() # DEPRECATED: ).count()
# DEPRECATED:
# 我的匹配:自有藏品匹配成功的寻号帖子数量 # 我的匹配:自有藏品匹配成功的寻号帖子数量
# 即 is_matched = 'confirmed' 的记录用户ID等于当前用户 # 即 is_matched = 'confirmed' 的记录用户ID等于当前用户
user_matched_count = 0 # DEPRECATED: user_matched_count = 0
if current_user: # DEPRECATED: if current_user:
user_matched_count = db.query(Information).filter( # DEPRECATED: user_matched_count = db.query(Information).filter(
Information.info_type == 'seek', # DEPRECATED: Information.info_type == 'seek',
Information.expect_number.isnot(None), # DEPRECATED: Information.expect_number.isnot(None),
Information.expect_number != '', # DEPRECATED: Information.expect_number != '',
Information.matched_user_id == current_user.f99_90_id, # DEPRECATED: Information.matched_user_id == current_user.f99_90_id,
Information.is_matched == 'confirmed' # DEPRECATED: Information.is_matched == 'confirmed'
).count() # DEPRECATED: ).count()
# DEPRECATED:
# 总共匹配:自有匹配成功 + 网络数据匹配成功 # 总共匹配:自有匹配成功 + 网络数据匹配成功
# 自有匹配成功is_matched = 'confirmed' # 自有匹配成功is_matched = 'confirmed'
# 网络数据匹配成功查询每个帖子的network_matched_count并求和 # 网络数据匹配成功查询每个帖子的network_matched_count并求和
seeks = db.query(Information).filter( # DEPRECATED: seeks = db.query(Information).filter(
Information.info_type == 'seek', # DEPRECATED: Information.info_type == 'seek',
Information.expect_number.isnot(None), # DEPRECATED: Information.expect_number.isnot(None),
Information.expect_number != '' # DEPRECATED: Information.expect_number != ''
).all() # DEPRECATED: ).all()
# DEPRECATED:
total_self_matched = 0 # DEPRECATED: total_self_matched = 0
total_network_matched = 0 # DEPRECATED: total_network_matched = 0
for seek in seeks: # DEPRECATED: for seek in seeks:
# 自身匹配成功 # 自身匹配成功
if seek.is_matched == 'confirmed': # DEPRECATED: if seek.is_matched == 'confirmed':
total_self_matched += 1 # DEPRECATED: total_self_matched += 1
# 网络数据匹配成功通过coolbot数据库查询 # 网络数据匹配成功通过coolbot数据库查询
if seek.expect_number: # DEPRECATED: if seek.expect_number:
network_count = match_collections_count_from_coolbot(seek.expect_number) # DEPRECATED: network_count = match_collections_count_from_coolbot(seek.expect_number)
total_network_matched += network_count # DEPRECATED: total_network_matched += network_count
# DEPRECATED:
total_matched_count = total_self_matched + total_network_matched # DEPRECATED: total_matched_count = total_self_matched + total_network_matched
# DEPRECATED:
return { # DEPRECATED: return {
"seekCount": seek_count, # DEPRECATED: "seekCount": seek_count,
"userMatchedCount": user_matched_count, # DEPRECATED: "userMatchedCount": user_matched_count,
"totalMatchedCount": total_matched_count # DEPRECATED: "totalMatchedCount": total_matched_count
} # DEPRECATED: }
# DEPRECATED:
# 批量解析行情数据API # 批量解析行情数据API
@router.post("/batch-parse") @router.post("/batch-parse")
async def batch_parse_deals(text: str = Body(..., embed=True)): async def batch_parse_deals(text: str = Body(..., embed=True)):

View File

@ -1,3 +1,7 @@
# seek - 寻配号路由
# Version: 0.0.3 (2026-04-24)
# 更新:添加缺失端点,清理废弃依赖
from fastapi import APIRouter, Depends, Query, HTTPException from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from pydantic import BaseModel from pydantic import BaseModel
@ -6,8 +10,13 @@ from datetime import datetime
from app.core.database import get_db from app.core.database import get_db
from app.core.auth import get_current_user from app.core.auth import get_current_user
from app.models.seek_info import SeekInfo from app.models.seek_info import SeekInfo
from app.models.models import User, Collection, Information from app.models.models import User, Collection
from sqlalchemy import text from app.utils.coolbot_matcher import (
match_pattern,
match_self_collections_count,
match_collections_count_from_coolbot,
match_collections_list_from_coolbot
)
router = APIRouter(prefix="/api/seek", tags=["寻配号"]) router = APIRouter(prefix="/api/seek", tags=["寻配号"])
@ -59,6 +68,11 @@ class SeekInfoResponse(BaseModel):
class Config: class Config:
from_attributes = True from_attributes = True
class MatchConfirmRequest(BaseModel):
info_id: str
contact: Optional[str] = None
collection_id: Optional[str] = None
# ============ API ============ # ============ API ============
@router.get("/list", response_model=list[SeekInfoResponse]) @router.get("/list", response_model=list[SeekInfoResponse])
def get_seek_list( def get_seek_list(
@ -83,22 +97,12 @@ def get_seek_list(
offset = (page - 1) * page_size offset = (page - 1) * page_size
items = query.offset(offset).limit(page_size).all() items = query.offset(offset).limit(page_size).all()
# 添加用户名和匹配数量
from app.routers.information import match_collections_count, match_collections_count_from_coolbot
result = [] result = []
for item in items: for item in items:
user = db.query(User).filter(User.f99_90_id == item.user_id).first() user = db.query(User).filter(User.f99_90_id == item.user_id).first()
user_name = user.f01_01_name if user else '匿名用户' user_name = user.f01_01_name if user else '匿名用户'
# 计算匹配数量 # 构建响应(不实时计算网络匹配,网络匹配在点击时再查)
matched_count = 0
network_matched_count = 0
if item.expect_number and len(item.expect_number) == 10:
if current_user and current_user.f99_90_id:
matched_count = match_collections_count(db, current_user.f99_90_id, item.expect_number)
network_matched_count = match_collections_count_from_coolbot(item.expect_number)
# 构建响应
result.append(SeekInfoResponse( result.append(SeekInfoResponse(
id=item.id, id=item.id,
user_id=item.user_id, user_id=item.user_id,
@ -119,8 +123,8 @@ def get_seek_list(
created_at=item.created_at, created_at=item.created_at,
updated_at=item.updated_at, updated_at=item.updated_at,
user_name=user_name, user_name=user_name,
matched_count=matched_count, matched_count=0,
network_matched_count=network_matched_count network_matched_count=0
)) ))
return result return result
@ -232,7 +236,9 @@ def delete_seek(
db.commit() db.commit()
return {"message": "删除成功"} return {"message": "删除成功"}
# 获取自有藏品匹配列表
# ============ 匹配相关API ============
@router.get("/my-match") @router.get("/my-match")
def get_seek_match( def get_seek_match(
info_id: str, info_id: str,
@ -254,7 +260,6 @@ def get_seek_match(
).all() ).all()
# 按号码特征模式匹配 # 按号码特征模式匹配
from app.routers.information import match_pattern
matched = [] matched = []
if info.expect_number and len(info.expect_number) == 10: if info.expect_number and len(info.expect_number) == 10:
pattern = info.expect_number[2:] pattern = info.expect_number[2:]
@ -280,7 +285,6 @@ def get_seek_match(
] ]
} }
# 获取网络数据匹配列表
@router.get("/network-match/{info_id}") @router.get("/network-match/{info_id}")
def get_network_match( def get_network_match(
info_id: str, info_id: str,
@ -288,8 +292,6 @@ def get_network_match(
db: Session = Depends(get_db) db: Session = Depends(get_db)
): ):
"""获取一尘数据库中匹配的藏品列表""" """获取一尘数据库中匹配的藏品列表"""
from app.routers.information import match_collections_list_from_coolbot
info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first() info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first()
if not info: if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在") raise HTTPException(status_code=404, detail="寻配号信息不存在")
@ -299,3 +301,107 @@ def get_network_match(
matched = match_collections_list_from_coolbot(info.expect_number, limit=limit) matched = match_collections_list_from_coolbot(info.expect_number, limit=limit)
return {"matched_count": len(matched), "collections": matched} return {"matched_count": len(matched), "collections": matched}
@router.post("/match-confirm")
def match_seek_confirm(
request: MatchConfirmRequest,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""确认匹配寻号 - 用户愿意交换联系方式给发布者"""
info = db.query(SeekInfo).filter(
SeekInfo.id == request.info_id,
SeekInfo.status == "active"
).first()
if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在")
# 检查是否已被匹配(一个寻号只能被一个用户匹配)
if info.is_matched == "matched":
raise HTTPException(status_code=400, detail="该寻号已被其他用户匹配")
# 检查是否是自己发布的
if info.user_id == current_user.f99_90_id:
raise HTTPException(status_code=400, detail="不能匹配自己发布的寻号")
# 更新匹配状态
info.is_matched = "matched"
info.matched_user_id = current_user.f99_90_id
info.matched_contact = request.contact or ''
# 更新发布寻号者的内容,显示有藏品被匹配
original_content = info.content or ""
match_info = f"\n藏品被{current_user.f01_01_name}匹配成功!联系方式:{request.collection_id or '已交换'}"
info.content = original_content + match_info
db.commit()
return {"message": "匹配成功,已通知发布者", "is_matched": "matched"}
@router.get("/matched-user/{info_id}")
def get_matched_user(
info_id: str,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""获取寻号的匹配者信息(仅发布者可见)"""
info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first()
if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在")
# 只有发布者可以看到匹配者信息
if info.user_id != current_user.f99_90_id:
raise HTTPException(status_code=403, detail="无权访问")
if not info.matched_user_id:
return {"message": "暂无匹配者"}
# 获取匹配者信息
matched_user = db.query(User).filter(User.f99_90_id == info.matched_user_id).first()
if not matched_user:
return {"message": "匹配者不存在"}
return {
"matched_user_id": info.matched_user_id,
"user_name": matched_user.f01_01_name,
"phone": matched_user.phone,
"matched_contact": info.matched_contact,
}
@router.get("/publisher/{info_id}")
def get_publisher_info(
info_id: str,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""获取寻号的发布者信息(仅匹配者可见)"""
info = db.query(SeekInfo).filter(SeekInfo.id == info_id).first()
if not info:
raise HTTPException(status_code=404, detail="寻配号信息不存在")
# 只有匹配者可以看到发布者信息
if not info.matched_user_id or info.matched_user_id != current_user.f99_90_id:
raise HTTPException(status_code=403, detail="无权访问")
# 获取发布者信息
publisher = db.query(User).filter(User.f99_90_id == info.user_id).first()
if not publisher:
return {"message": "发布者不存在"}
# 从content中解析联系方式
contact = ''
if info.content:
import re
match = re.search(r'联系方式[:\s]*(.+?)(?:\n|$)', info.content)
if match:
contact = match.group(1).strip()
return {
"user_id": info.user_id,
"user_name": publisher.f01_01_name,
"phone": publisher.phone,
"contact": contact,
}

View File

@ -0,0 +1,208 @@
# coolbot_matcher - 一尘数据库号码匹配工具
# Version: 0.0.1 (2026-04-24)
# 描述:从一尘数据库(coolbot_data)查询匹配的藏品号码
from typing import List
from sqlalchemy import text
from sqlalchemy.orm import Session
from app.core.coolbot_db import coolbot_engine
def match_pattern(col_number: str, pattern: str) -> bool:
"""匹配号码特征模式
通配符规则:
- X = 任意数字
- A = 非4
- B = 非47
- C = 非347
- D = 非247
- E = 非2347
"""
if not col_number or not pattern:
return False
if len(col_number) != len(pattern):
return False
for i, p in enumerate(pattern):
c = col_number[i]
if p == 'X':
continue # 任意数字
elif p == 'A':
if c == '4':
return False
elif p == 'B':
if c == '4':
return False
if i < len(col_number) - 1 and col_number[i+1] == '7' and pattern[i+1] == 'X':
return False
elif p == 'C':
if c in '347':
return False
elif p == 'D':
if c in '247':
return False
elif p == 'E':
if c in '2347':
return False
elif p == 'L':
# L = 带4
if c != '4':
return False
elif p == 'N':
# N = 无4
if c == '4':
return False
else:
if c != p:
return False
return True
def match_self_collections_count(db: Session, user_id: str, expect_number: str) -> int:
"""根据号码特征计算匹配藏品数量(从用户自有藏品)
Args:
db: 数据库会话
user_id: 用户ID
expect_number: 期望号码 "J012345678" (固定J0前缀+8位特征)
Returns:
匹配的藏品数量
"""
from app.models.models import Collection
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
# 获取用户所有藏品
collections = db.query(Collection).filter(
Collection.f99_91_user_id == user_id,
Collection.f01_04_status == "in_collection"
).all()
count = 0
for c in collections:
number = c.f02_10_prefix_serial or ''
if len(number) >= 10 and number.startswith('J0'):
col_pattern = number[2:10]
if match_pattern(col_pattern, pattern):
count += 1
elif len(number) >= 8:
col_pattern = number[:8]
if match_pattern(col_pattern, pattern):
count += 1
return count
def match_collections_count_from_coolbot(expect_number: str) -> int:
"""根据号码特征计算匹配藏品数量从coolbot_data数据库
Args:
expect_number: 期望号码 "J012345678" (固定J0前缀+8位特征)
Returns:
匹配的藏品数量
"""
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
query = 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%'
""")
try:
with coolbot_engine.connect() as conn:
result = conn.execute(query)
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数据库
Args:
expect_number: 期望号码 "J012345678"
limit: 返回的最大数量
Returns:
匹配的藏品列表
"""
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 []
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 []

View File

@ -1,5 +1,25 @@
# 版本更新记录 # 版本更新记录
## v0.0.7 (2026-04-24)
### 代码清理
- **coolbot_matcher.py** (新建)
- 功能:创建一尘数据库号码匹配工具模块
- 包含match_pattern, match_self_collections_count, match_collections_count_from_coolbot, match_collections_list_from_coolbot
- **seek.py**
- 功能:更新导入,添加缺失端点
- 新增端点:/match-confirm, /matched-user/{id}, /publisher/{id}
- 优化:移除列表接口网络匹配实时计算,提升加载速度
- **information.py**
- 清理注释废弃的seek/deal重复端点统一使用/api/seek/*和/api/deal/*
- **News.jsx**
- 迁移seek相关API从/api/information/*迁移到/api/seek/*
---
## v1.2.98 (2026-04-19) ## v1.2.98 (2026-04-19)
### 前端更新 ### 前端更新

View File

@ -1,9 +1,9 @@
{ {
"version": "0.0.6", "version": "0.0.7",
"updated": "2026-04-19", "updated": "2026-04-24",
"modules": { "modules": {
"frontend": { "frontend": {
"version": "0.0.6", "version": "0.0.7",
"pages": { "pages": {
"Add": "0.0.1", "Add": "0.0.1",
"Admin": "0.0.1", "Admin": "0.0.1",
@ -12,7 +12,7 @@
"Home": "0.0.1", "Home": "0.0.1",
"List": "0.0.1", "List": "0.0.1",
"Login": "0.0.1", "Login": "0.0.1",
"News": "0.0.1", "News": "0.0.2",
"News_YichensBoard": "0.0.1", "News_YichensBoard": "0.0.1",
"Settings": "0.0.1", "Settings": "0.0.1",
"Stats": "0.0.1", "Stats": "0.0.1",
@ -23,16 +23,16 @@
} }
}, },
"backend": { "backend": {
"version": "0.0.6", "version": "0.0.7",
"routers": { "routers": {
"auth": "0.0.1", "auth": "0.0.1",
"collections": "0.0.1", "collections": "0.0.1",
"deal": "0.0.1", "deal": "0.0.1",
"information": "0.0.1", "information": "0.0.2",
"news": "0.0.1", "news": "0.0.1",
"ocr": "0.0.1", "ocr": "0.0.1",
"operations": "0.0.1", "operations": "0.0.1",
"seek": "0.0.1", "seek": "0.0.2",
"users": "0.0.1", "users": "0.0.1",
"yichens": "0.0.1" "yichens": "0.0.1"
}, },

View File

@ -1,7 +1,7 @@
/** /**
* News - 资讯列表页面 * News - 资讯列表页面
* Version: 0.0.1 * Version: 0.0.2 (2026-04-24)
* 更新 * 更新迁移seek相关API到/api/seek/*
*/ */
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
@ -195,7 +195,7 @@ export default function News() {
if (!token) { alert('请先登录'); return } if (!token) { alert('请先登录'); return }
try { try {
const phone = getUserPhone() const phone = getUserPhone()
const res = await fetch(`${API_BASE}/api/information/seek/match-confirm`, { const res = await fetch(`${API_BASE}/api/seek/match-confirm`, {
method: 'POST', method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ info_id: infoId, contact: phone || '用户已同意' }) body: JSON.stringify({ info_id: infoId, contact: phone || '用户已同意' })
@ -232,7 +232,7 @@ export default function News() {
if (!token) { alert('请先登录'); return } if (!token) { alert('请先登录'); return }
} }
try { try {
const res = await fetch(`${API_BASE}/api/information/seek/matched-user/${infoId}`, { headers: { Authorization: `Bearer ${token}` } }) const res = await fetch(`${API_BASE}/api/seek/matched-user/${infoId}`, { headers: { Authorization: `Bearer ${token}` } })
console.log('Matched user response:', res.status) console.log('Matched user response:', res.status)
const data = await res.json() const data = await res.json()
console.log('Matched user data:', data) console.log('Matched user data:', data)
@ -245,7 +245,7 @@ export default function News() {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
if (!token) { alert('请先登录'); return } if (!token) { alert('请先登录'); return }
try { try {
const res = await fetch(`${API_BASE}/api/information/seek/publisher/${infoId}`, { headers: { Authorization: `Bearer ${token}` } }) const res = await fetch(`${API_BASE}/api/seek/publisher/${infoId}`, { headers: { Authorization: `Bearer ${token}` } })
console.log('Publisher response:', res.status) console.log('Publisher response:', res.status)
const data = await res.json() const data = await res.json()
console.log('Publisher data:', data) console.log('Publisher data:', data)
@ -257,7 +257,7 @@ export default function News() {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
if (!token) { alert('请先登录'); return } if (!token) { alert('请先登录'); return }
try { try {
const res = await fetch(`${API_BASE}/api/information/seek/match?info_id=${infoId}`, { const res = await fetch(`${API_BASE}/api/seek/my-match?info_id=${infoId}`, {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}) })
const data = await res.json() const data = await res.json()
@ -331,7 +331,7 @@ export default function News() {
try { try {
// //
const content = (editingSeek.content || '') + '\n联系方式: ' + editingSeek.contact const content = (editingSeek.content || '') + '\n联系方式: ' + editingSeek.contact
await fetch(`${API_BASE}/api/information/${editingSeek.id}`, { await fetch(`${API_BASE}/api/seek/${editingSeek.id}`, {
method: 'PUT', method: 'PUT',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }, headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -355,14 +355,13 @@ export default function News() {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
// editioncategory // editioncategory
const categoryMap = { '龙钞': '龙钞', '马钞': '马钞', '蛇钞': '蛇钞' } const categoryMap = { '龙钞': '龙钞', '马钞': '马钞', '蛇钞': '蛇钞' }
const res = await fetch(`${API_BASE}/api/information/`, { const res = await fetch(`${API_BASE}/api/seek/`, {
method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
title: seekForm.title, title: seekForm.title,
content, content,
info_type: 'seek',
expect_category: seekForm.edition, expect_category: seekForm.edition,
expect_number: seekForm.features ? 'J0' + seekForm.features : None expect_number: seekForm.features ? 'J0' + seekForm.features : null
}) })
}) })
const data = await res.json() const data = await res.json()