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' && (
-
-
-