From ad2494703710357581472848ba4e01c8ad2d0df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B2=E8=BE=B0=E7=94=9F=E4=BA=A7?= Date: Sat, 28 Mar 2026 15:31:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BB=E9=85=8D=E5=8F=B7=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E7=89=88=20v1.2.24=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/News.jsx.bak | 827 -------------------------------- 1 file changed, 827 deletions(-) delete mode 100644 frontend/src/pages/News.jsx.bak diff --git a/frontend/src/pages/News.jsx.bak b/frontend/src/pages/News.jsx.bak deleted file mode 100644 index 95e4006..0000000 --- a/frontend/src/pages/News.jsx.bak +++ /dev/null @@ -1,827 +0,0 @@ -import React, { useState, useEffect } from 'react' -// 本地获取用户手机号 -const getUserPhone = () => { - try { - const user = JSON.parse(localStorage.getItem('user') || '{}') - console.log('getUserPhone user:', user) - // Try multiple possible field names - return user.phone || user.phoneNumber || user.mobile || user.tel || '' - } catch { return '' } -} - -// 资讯页面 - 展示寻配号和行情信息(所有人可见) -export default function News() { - const [activeTab, setActiveTab] = useState(localStorage.getItem('news_activeTab') || 'seek') - const [showSeekPublish, setShowSeekPublish] = useState(false) - const [showMySeeks, setShowMySeeks] = useState(false) // 我的寻号 - const [showContactId, setShowContactId] = useState(null) // 显示联系方式的寻号ID - const [showCommentId, setShowCommentId] = useState(null) // 显示评论输入的寻号ID - const [commentText, setCommentText] = useState('') // 评论内容 - const [comments, setComments] = useState({}) // 存储各寻号的评论 - const [matchedStatus, setMatchedStatus] = useState({}) // 存储各寻号的匹配状态 - const [showMatchList, setShowMatchList] = useState(false) - const [matchCollections, setMatchCollections] = useState([]) - const [customModal, setCustomModal] = useState({show: false, title: '', content: ''}) - const [seekForm, setSeekForm] = useState({ - edition: '龙钞', type: '', category: '寻号', price: '', matchType: '模糊', features: '', content: '', title: '', contact: getUserPhone() || '' - }) - const [infoList, setInfoList] = useState([]) - const [viewMode, setViewMode] = useState('all') - const [loading, setLoading] = useState(false) - - const API_BASE = 'http://47.103.9.192:3000' - const currentUser = localStorage.getItem('token') ? { id: 'logged_in' } : null - - // 获取资讯列表 - useEffect(() => { - fetchInfoList() - }, [activeTab]) - - // 自动生成寻号标题 - useEffect(() => { - const title = `「寻号 ${seekForm.edition || '龙钞,马钞,蛇钞'} J0${seekForm.features || 'XXXXXXXX'}」` - setSeekForm(prev => ({...prev, title})) - }, [seekForm.edition, seekForm.features]) - - const fetchInfoList = async () => { - setLoading(true) - try { - // 寻配号对所有人公开,无需登录即可查看 - const token = localStorage.getItem('token') - // 根据tab获取不同类型的数据 - const type = activeTab === 'seek' ? 'seek' : 'deal' - // 始终传递token,以便获取准确的matched_count - const headers = token ? { Authorization: `Bearer ${token}` } : {} - const res = await fetch(`${API_BASE}/api/information/list?info_type=${type}`, { headers }) - const data = await res.json() - console.log('资讯列表:', data) - setInfoList(data || []) - } catch (e) { - console.error(e) - } - setLoading(false) - } - - // 获取匹配藏品列表 - - - // 获取寻号评论 - const fetchComments = async (infoId) => { - // 每次都重新获取评论 - try { - const res = await fetch(`${API_BASE}/api/information/comments/${infoId}`) - const data = await res.json() - setComments(prev => ({...prev, [infoId]: data || []})) - } catch (e) { - console.error('获取评论失败:', e) - } - } - - // 添加评论 - const addComment = async (infoId) => { - if (!commentText.trim()) { alert('请输入评论内容'); return } - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - const res = await fetch(`${API_BASE}/api/information/comment`, { - method: 'POST', - headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, - body: JSON.stringify({ information_id: infoId, content: commentText }) - }) - const data = await res.json() - if (data.message === '留言成功' || data.message === '评论成功') { - setCommentText('') - // 强制刷新评论列表,先清空缓存 - setComments(prev => { - const newComments = {...prev} - delete newComments[infoId] - return newComments - }) - // 然后重新获取 - setTimeout(() => fetchComments(infoId), 100) - // 确保停留在寻号 tab - if (activeTab !== 'seek') { - setActiveTab('seek') - } - alert('留言成功!') - } else { - alert(data.detail || '留言失败') - } - } catch (e) { - console.error('留言失败:', e) - alert('留言失败,请重试') - } - } - - // 匹配并联系藏友 - const matchAndContact = async (infoId) => { - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - 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 }) - }) - const data = await res.json() - if (data.message === '匹配成功,已通知发布者') { - setMatchedStatus(prev => ({...prev, [infoId]: 'matched'})) - setShowContactId(infoId) // 显示联系方式 - setCustomModal({show: true, title: '匹配成功', content: '已通知发布者,请等待对方联系'}) - fetchInfoList() // 刷新列表 - } - } catch (e) { - alert('操作失败: ' + e.message) - } - } - const fetchMatchedUserInfo = async (infoId) => { - console.log('fetchMatchedUserInfo called with:', infoId) - let token = localStorage.getItem('token') - if (!token) { - // Try to refresh token - const username = localStorage.getItem('username') - const password = localStorage.getItem('password') - if (username && password) { - const form = new FormData() - form.append('username', username) - form.append('password', password) - const loginRes = await fetch(`${API_BASE}/api/auth/login`, { method: 'POST', body: form }) - const loginData = await loginRes.json() - if (loginData.access_token) { - token = loginData.access_token - localStorage.setItem('token', token) - } - } - if (!token) { alert('请先登录'); return } - } - try { - const res = await fetch(`${API_BASE}/api/information/seek/matched-user/${infoId}`, { headers: { Authorization: `Bearer ${token}` } }) - 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 || '未提供'}`}) - else if (data.detail) alert(data.detail) - } catch (e) { console.error(e) } - } - const fetchPublisherInfo = async (infoId) => { - console.log('fetchPublisherInfo called with:', infoId) - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - const res = await fetch(`${API_BASE}/api/information/seek/publisher/${infoId}`, { headers: { Authorization: `Bearer ${token}` } }) - 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 || '未提供'}`}) - else if (data.detail) alert(data.detail) - } catch (e) { console.error(e) } - } - const fetchMatchCollections = async (infoId) => { - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - const res = await fetch(`${API_BASE}/api/information/seek/match?info_id=${infoId}`, { - headers: { Authorization: `Bearer ${token}` } - }) - const data = await res.json() - console.log('匹配结果:', data) - console.log('匹配数量:', data.matched_count) - console.log('藏品列表:', data.collections) - setMatchCollections(data.collections || []) - setShowMatchList(true) - } catch (e) { - console.error('获取匹配藏品失败:', e) - alert('获取匹配藏品失败: ' + e.message) - } - } - - // 获取当前用户ID - const getUserId = () => { - try { - const user = JSON.parse(localStorage.getItem('user') || '{}') - return user.id || user.user_id || user.f99_90_id || null - } catch { return null } - } - const currentUserId = getUserId() - - // 获取我的寻号列表 - const [mySeekList, setMySeekList] = useState([]) - const [myMatchedList, setMyMatchedList] = useState([]) - const [editingSeek, setEditingSeek] = useState(null) - const fetchMySeeks = async () => { - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - const res = await fetch(`${API_BASE}/api/information/my/list`, { - headers: { Authorization: `Bearer ${token}` } - }) - const data = await res.json() - // 过滤出寻号类型的并筛选当前用户 - const seeks = Array.isArray(data) ? data.filter(item => item.info_type === 'seek' && item.user_id === currentUserId) : [] - setMySeekList(seeks) - setInfoList(seeks) // 在主列表显示 - } catch (e) { console.error(e) } - } - - // 获取我已匹配的寻号列表 - const fetchMyMatches = async () => { - const token = localStorage.getItem('token') - if (!token) { alert('请先登录'); return } - try { - const res = await fetch(`${API_BASE}/api/information/list?info_type=seek`, { - headers: { Authorization: `Bearer ${token}` } - }) - const data = await res.json() - // 筛选我已匹配的(matched_user_id等于当前用户ID) - const matched = data.filter(item => item.is_matched === 'matched' && item.matched_user_id === currentUserId) - setMyMatchedList(matched) - setInfoList(matched) // 在主列表显示 - } catch (e) { console.error(e) } - } - - // 更新寻号 - const handleUpdateSeek = async () => { - if (!editingSeek) return - const token = localStorage.getItem('token') - try { - // 解析正文中的号码特征和联系方式 - const content = (editingSeek.content || '') + '\n联系方式: ' + editingSeek.contact - await fetch(`${API_BASE}/api/information/${editingSeek.id}`, { - method: 'PUT', - headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }, - body: JSON.stringify({ - title: editingSeek.title, - content, - expect_category: editingSeek.edition, - expect_number: editingSeek.features ? 'J0' + editingSeek.features : null - }) - }) - setEditingSeek(null) - fetchMySeeks() - } catch (e) { alert('更新失败') } - } - - const handleSeekPublish = async () => { - const phone = getUserPhone() - const finalContact = seekForm.contact || phone || '' - if (!finalContact) { alert('请填写联系方式'); return } - const content = (seekForm.content ? seekForm.content + '\n' : '') + (seekForm.price ? `价格: ${seekForm.price}` : '') + (seekForm.features ? '\n号码特征: J0' + seekForm.features : '') + '\n联系方式: ' + finalContact - try { - const token = localStorage.getItem('token') - // 从edition映射到category - const categoryMap = { '龙钞': '龙钞', '马钞': '马钞', '蛇钞': '蛇钞' } - const res = await fetch(`${API_BASE}/api/information/`, { - method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, - body: JSON.stringify({ - title: seekForm.title, - content, - info_type: 'seek', - expect_category: seekForm.edition, - expect_number: seekForm.features ? 'J0' + seekForm.features : None - }) - }) - const data = await res.json() - if (data.id || data.code === 0) { - alert('发布成功!') - setShowSeekPublish(false) - setSeekForm({ edition: '龙钞', type: '', category: '寻号', price: '', matchType: '模糊', features: '', content: '', title: '', contact: getUserPhone() || '' }) - fetchInfoList() - } else { alert(data.message || '发布失败') } - } catch (e) { alert('发布失败: ' + e.message) } - } - - // Tab切换 - const tabs = [ - { key: 'seek', label: '🔍 寻配号' }, - { key: 'deal', label: '💰 成交行情' } - ] - - const formatDate = (dateStr) => { - if (!dateStr) return '-' - const date = new Date(dateStr) - return `${date.getMonth() + 1}/${date.getDate()}` - } - - return ( -
- {/* Tab导航 */} -
- {tabs.map(tab => ( -
{ setActiveTab(tab.key); localStorage.setItem('news_activeTab', tab.key); }} - style={{ - padding: '10px 20px', - borderRadius: '8px', - background: activeTab === tab.key ? '#3b82f6' : 'transparent', - color: '#fff', - cursor: 'pointer', - whiteSpace: 'nowrap', - fontSize: '14px' - }} - > - {tab.label} -
- ))} -
- - {/* 资讯列表 */} -
- {showSeekPublish && activeTab === 'seek' && ( -
-
-
- {['龙钞','马钞','蛇钞'].map(item => { - const isSelected = seekForm.edition ? seekForm.edition.split(',').includes(item) : false - return ( - - ) - })} -
-
-
- setSeekForm({...seekForm, price: e.target.value})} placeholder="请输入价格" - style={{ width: '100%', padding: '8px', marginTop: '6px', background: '#0f172a', border: '1px solid #334155', borderRadius: '6px', color: '#fff', fontSize: '13px', boxSizing: 'border-box' }} /> -
-
-
- {[0,1,2,3,4,5,6,7,8,9].map(i => { - const isFixed = i < 2 - const char = i === 0 ? 'J' : (i === 1 ? '0' : (seekForm.features[i - 2] || '')) - const isDigit = /[0-9]/.test(char) - const letterColor = isFixed ? '#10b981' : (isDigit ? '#fff' : ({ X: '#94a3b8', A: '#f472b6', B: '#60a5fa', C: '#34d399', D: '#fbbf24', E: '#a78bfa', F: '#fb923c', G: '#22d3ee' }[char] || '#fff')) - return { if (el) el.dataset.index = i }} type="text" maxLength={1} - value={char} - readOnly={isFixed} - onChange={(e) => { - if (i < 2) return - const val = e.target.value.toUpperCase().replace(/[^0-9XABCFG]/g, '') - const newFeatures = (seekForm.features || '').split('') - while (newFeatures.length < 8) newFeatures.push('') - newFeatures[i - 2] = val - setSeekForm({...seekForm, features: newFeatures.join('')}) - // 自动跳转下一个 - if (val && i < 9) { - setTimeout(() => { - const nextInput = document.querySelector(`input[data-index="${i+1}"]`) - if (nextInput) nextInput.focus() - }, 50) - } - }} - onKeyDown={(e) => { - // 按Delete或Backspace且当前为空时,跳回前一个 - if ((e.key === 'Backspace' || e.key === 'Delete') && !char && i > 2) { - setTimeout(() => { - const prevInput = document.querySelector(`input[data-index="${i-1}"]`) - if (prevInput) prevInput.focus() - }, 50) - } - }} - style={{ width: '32px', height: '36px', textAlign: 'center', padding: '6px', background: '#0f172a', border: '1px solid #334155', borderRadius: '4px', color: letterColor, fontSize: '14px', boxSizing: 'border-box' }} /> - })} -
-
- 备注说明:X=任意数字 A=非4 B=非47 C=非347 D=非247 E=非2347 F=非23457 G=非123457 -
-
-
- setSeekForm({...seekForm, title: e.target.value})} /> -
-
-