From 7009d1126ce11a30e9662220bc21419645a43d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B2=E8=BE=B0=E7=94=9F=E4=BA=A7?= Date: Sun, 29 Mar 2026 17:04:09 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.25=20-=20Info=E9=A1=B5=E9=9D=A2=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E7=89=88=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=AF=BB=E5=8F=B7?= =?UTF-8?q?/=E8=A1=8C=E6=83=85=E9=A1=B6=E9=83=A8Tab=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E3=80=81=E5=88=97=E8=A1=A8=E7=AD=9B=E9=80=89=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=88=E5=85=A8=E9=83=A8/=E5=AF=BB=E5=8F=B7/=E8=A1=8C?= =?UTF-8?q?=E6=83=85=EF=BC=89=E3=80=81=E5=8F=91=E5=B8=83=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A0=87=E7=AD=BE=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- config/VERSION | 2 +- frontend/src/pages/Info.jsx | 563 +++++++++++++++++++++++++++--------- 3 files changed, 424 insertions(+), 143 deletions(-) diff --git a/VERSION b/VERSION index e4ae45b..445399f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION=1.2.24 +VERSION=1.2.25 diff --git a/config/VERSION b/config/VERSION index e4ae45b..445399f 100644 --- a/config/VERSION +++ b/config/VERSION @@ -1 +1 @@ -VERSION=1.2.24 +VERSION=1.2.25 diff --git a/frontend/src/pages/Info.jsx b/frontend/src/pages/Info.jsx index 24e3557..449a491 100644 --- a/frontend/src/pages/Info.jsx +++ b/frontend/src/pages/Info.jsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react' +// 信息页面 - 寻配号发布和发布管理(包含寻号/行情区分) export default function Info() { // 检查登录状态,未登录则跳转到登录页 if (!localStorage.getItem('token')) { @@ -7,129 +8,233 @@ export default function Info() { return null } + // 顶部tab:寻配号发布 / 发布管理 const [activeTab, setActiveTab] = useState('publish') const [showPublish, setShowPublish] = useState(false) const [myList, setMyList] = useState([]) const [loading, setLoading] = useState(false) const [editingItem, setEditingItem] = useState(null) + const [filterType, setFilterType] = useState('all') // all/seek/deal const [formData, setFormData] = useState({ edition: '龙钞', type: '标百', isGraded: true, category: '成交', source: '直播', title: '' }) - // content使用原生DOM + + // 寻配号发布表单(新版) + const [seekForm, setSeekForm] = useState({ + edition: '龙钞,马钞,蛇钞', price: '', features: '', contact: '', content: '' + }) + + const API_BASE = localStorage.getItem('API_BASE') || '' useEffect(() => { if (activeTab === 'manage') fetchMyList() }, [activeTab]) - // 自动生成标题 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') || '' + // 自动生成标题 + if (seekForm.edition || seekForm.features) { + const title = `「寻号 ${seekForm.edition || '龙钞,马钞,蛇钞'} J0${seekForm.features || 'XXXXXXXX'}」` + setSeekForm(prev => ({ ...prev, title })) + } + }, [seekForm.edition, seekForm.features]) const fetchMyList = async () => { setLoading(true) try { const token = localStorage.getItem('token') - const res = await fetch(`${API_BASE}/api/information/my/list`, { headers: { Authorization: `Bearer ${token}` } }) - setMyList(res.ok ? await res.json() : []) - } catch (e) { console.error(e) } + const res = await fetch(`${API_BASE}/api/information/my/list`, { + headers: { Authorization: `Bearer ${token}` } + }) + if (res.ok) { + const data = await res.json() + setMyList(data || []) + } + } catch (e) { + console.error(e) + } setLoading(false) } - const handlePublish = async () => { - if (!formData.title) { alert('请填写标题'); return } + // 发布寻配号 + const handlePublishSeek = async () => { + if (!seekForm.contact) { + 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({ title: formData.title, content: document.getElementById('publishContent')?.value || '', info_type: formData.category === '成交' ? 'deal' : 'seek' }) + method: 'POST', + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + title: seekForm.title, + content: document.getElementById('seekContent')?.value || seekForm.content, + info_type: 'seek', + expect_category: seekForm.edition, + expect_number: seekForm.features ? `J0${seekForm.features}` : null + }) + }) + const data = await res.json() + if (data.id || data.code === 0) { + alert('发布成功!') + setShowPublish(false) + setSeekForm({ edition: '龙钞,马钞,蛇钞', price: '', features: '', contact: '', content: '', title: '' }) + const contentEl = document.getElementById('seekContent') + if (contentEl) contentEl.value = '' + fetchMyList() + } else { + alert(data.message || '发布失败') + } + } catch (e) { + alert('发布失败: ' + e.message) + } + } + + // 发布行情 + const handlePublishDeal = async () => { + const content = document.getElementById('publishContent')?.value || '' + 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({ + title: formData.title, + content: content, + 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: '直播', title: '' }) - const el = document.getElementById('publishContent'); if(el) el.value = '' + const contentEl = document.getElementById('publishContent') + if (contentEl) contentEl.value = '' fetchMyList() - } else { alert(data.message || '发布失败') } - } catch (e) { alert('发布失败: ' + e.message) } + } else { + alert(data.message || '发布失败') + } + } catch (e) { + alert('发布失败: ' + e.message) + } } + // 删除 const handleDelete = async (id) => { if (!confirm('确定删除这条信息吗?')) return try { const token = localStorage.getItem('token') - const res = await fetch(`${API_BASE}/api/information/${id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } }) - if (res.ok) { alert('删除成功'); fetchMyList() } else { alert('删除失败') } - } catch (e) { alert('删除失败: ' + e.message) } + const res = await fetch(`${API_BASE}/api/information/${id}`, { + method: 'DELETE', + headers: { Authorization: `Bearer ${token}` } + }) + if (res.ok) { + alert('删除成功') + fetchMyList() + } else { + alert('删除失败') + } + } catch (e) { + alert('删除失败: ' + e.message) + } } - const handleEdit = (item) => setEditingItem({ id: item.id, title: item.title, content: item.content }) + // 编辑 + const handleEdit = (item) => { + setEditingItem({ id: item.id, title: item.title, content: item.content }) + } - const handleSaveEdit = async () => { + const saveEdit = async () => { if (!editingItem) return try { const token = localStorage.getItem('token') const res = await fetch(`${API_BASE}/api/information/${editingItem.id}`, { - method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, + method: 'PUT', + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json' + }, body: JSON.stringify({ title: editingItem.title, content: editingItem.content }) }) - if (res.ok) { alert('保存成功'); setEditingItem(null); fetchMyList() } else { alert('保存失败') } - } catch (e) { alert('保存失败: ' + e.message) } + if (res.ok) { + alert('保存成功') + setEditingItem(null) + fetchMyList() + } else { + alert('保存失败') + } + } catch (e) { + alert('保存失败: ' + e.message) + } } - const BtnGroup = ({ options, value, onChange, label }) => ( -
-
{label}
-
- {options.map(opt => ( - - ))} -
-
- ) + const getUserPhone = () => { + try { + const user = JSON.parse(localStorage.getItem('user') || '{}') + return user.phone || user.phoneNumber || user.mobile || user.tel || '' + } catch { + return '' + } + } - const Card = ({ children, title, action }) => ( -
- {title &&
-

{title}

- {action} -
} - {children} -
- ) + useEffect(() => { + setSeekForm(prev => ({ ...prev, contact: getUserPhone() })) + }, []) - const formatDate = (d) => d ? new Date(d).toLocaleString('zh-CN').slice(0, 16) : '-' + // 格式化日期 + const formatDate = (date) => { + if (!date) return '-' + return new Date(date).toLocaleString('zh-CN').slice(0, 16) + } + + // 过滤后的列表 + const filteredList = myList.filter(item => filterType === 'all' || item.info_type === filterType) return (
- {/* 顶部标签 */} + {/* 顶部 Tab 切换 */}
- {[{ key: 'publish', label: '📝 寻配号发布' }, { key: 'manage', label: '📋 发布管理' }].map(t => ( -
setActiveTab(t.key)} - style={{ flex: 1, padding: '12px 16px', borderRadius: '10px', background: activeTab === t.key ? 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)' : 'transparent', - color: activeTab === t.key ? '#fff' : '#9ca3af', cursor: 'pointer', textAlign: 'center', fontSize: '14px', fontWeight: '600', transition: 'all 0.3s' }}> - {t.label} + {[ + { key: 'publish', label: '📝 寻配号发布' }, + { key: 'manage', label: '📋 发布管理' } + ].map(tab => ( +
setActiveTab(tab.key)} + style={{ + flex: 1, + padding: '12px 16px', + borderRadius: '10px', + background: activeTab === tab.key ? 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)' : 'transparent', + color: activeTab === tab.key ? '#fff' : '#9ca3af', + cursor: 'pointer', + textAlign: 'center', + fontSize: '14px', + fontWeight: '600', + transition: 'all 0.3s' + }} + > + {tab.label}
))}
- {/* 寻配号发布 - 提示页面 */} + {/* 寻配号发布页 */} {activeTab === 'publish' && (
📝
@@ -138,123 +243,299 @@ export default function Info() {
)} - {/* 发布管理 */} + {/* 发布管理页 */} {activeTab === 'manage' && (
- -
-
- {/* 发布表单 */} + {/* 发布表单 - 两个Tab:寻配号 / 行情 */} {showPublish && (
- setFormData({...formData, edition: v})} /> + {/* 内部Tab:寻配号 / 行情 */} +
+ + +
-
-
-
类型
-
- {['标百', '标十', '单张'].map(t => ( - - ))} + {/* 寻配号表单 */} +
+
+ +
+ {['龙钞', '马钞', '蛇钞'].map(ed => { + const selected = seekForm.edition?.split(',').includes(ed) + return ( + + ) + })}
-
-
是否评级
-