diff --git a/backend/app/routers/yichens.py b/backend/app/routers/yichens.py
index 331be20..9b55df7 100644
--- a/backend/app/routers/yichens.py
+++ b/backend/app/routers/yichens.py
@@ -195,7 +195,8 @@ async def get_today_stats(db: Session = Depends(get_coolbot_db)):
SUM(CASE WHEN post_type = 'normal' THEN 1 ELSE 0 END) as others,
SUM(CASE WHEN category LIKE '%龙%' THEN 1 ELSE 0 END) as dragons,
SUM(CASE WHEN category LIKE '%马%' THEN 1 ELSE 0 END) as horses,
- SUM(CASE WHEN category LIKE '%蛇%' THEN 1 ELSE 0 END) as snakes
+ SUM(CASE WHEN category LIKE '%蛇%' THEN 1 ELSE 0 END) as snakes,
+ SUM(CASE WHEN title LIKE '%天马%' OR content LIKE '%天马%' THEN 1 ELSE 0 END) as tianma
FROM yichens_posts
WHERE post_time >= CURRENT_DATE
"""
@@ -205,9 +206,10 @@ async def get_today_stats(db: Session = Depends(get_coolbot_db)):
"deals": result[1] or 0,
"wants": result[2] or 0,
"others": result[3] or 0,
- "dragons": result[3] or 0,
- "horses": result[4] or 0,
- "snakes": result[5] or 0
+ "dragons": result[4] or 0,
+ "horses": result[5] or 0,
+ "snakes": result[6] or 0,
+ "tianma": result[7] or 0
}
@router.get("/stats/hour")
diff --git a/config/VERSION b/config/VERSION
index 79ee983..f6594fa 100644
--- a/config/VERSION
+++ b/config/VERSION
@@ -1 +1 @@
-VERSION=1.2.43
+VERSION=1.2.45
diff --git a/frontend/index.html b/frontend/index.html
index 42efbe9..cdce529 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -4,7 +4,7 @@
-
甲辰收藏 v1.2.42
+ 甲辰收藏 v1.2.45
diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx
index dc0262b..19770b4 100644
--- a/frontend/src/pages/Home.jsx
+++ b/frontend/src/pages/Home.jsx
@@ -5,6 +5,7 @@ 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 currentPath = window.location.hash.slice(1) || '/'
useEffect(() => {
@@ -54,6 +55,13 @@ export default function Home() {
}
}, [])
+ // 获取一尘看板数据
+ useEffect(() => {
+ fetch('/api/yichens/stats/today').then(res => res.json()).then(data => {
+ setYichensStats(data || {})
+ }).catch(() => {})
+ }, [])
+
// 检查是否为管理员
const isAdmin = user && user.role === 'admin'
@@ -138,6 +146,37 @@ export default function Home() {
))}
+ {/* 一尘看板数据 */}
+
+
📊 一尘今日数据
+
+
+
{yichensStats.total || 0}
+
总帖子
+
+
+
{yichensStats.deals || 0}
+
出售
+
+
+
{yichensStats.wants || 0}
+
求购
+
+
+
{yichensStats.dragons || 0}
+
龙钞
+
+
+
{yichensStats.horses || 0}
+
马钞
+
+
+
{yichensStats.tianma || 0}
+
天马
+
+
+
+
{/* 快捷操作 */}
快捷操作
diff --git a/frontend/src/pages/YichensBoard.jsx b/frontend/src/pages/YichensBoard.jsx
index 0785a51..7af8ba1 100644
--- a/frontend/src/pages/YichensBoard.jsx
+++ b/frontend/src/pages/YichensBoard.jsx
@@ -10,6 +10,7 @@ export default function YichensBoard() {
const [categoryFilter, setCategoryFilter] = useState('')
const [page, setPage] = useState(1)
const [totalPosts, setTotalPosts] = useState(0)
+ const [searchKeyword, setSearchKeyword] = useState('')
const API_BASE = localStorage.getItem('API_BASE') || ''
const today = new Date()
@@ -54,6 +55,18 @@ export default function YichensBoard() {
data = data.filter(p => p.category && !p.category.includes('龙') && !p.category.includes('纪念钞') && !p.category.includes('蛇') && !p.category.includes('马'))
}
}
+ // 搜索关键词过滤 - 强匹配(完全包含)
+ if (searchKeyword) {
+ const kw = searchKeyword.trim()
+ if (kw) {
+ data = data.filter(p =>
+ (p.title && p.title.includes(kw)) ||
+ (p.content && p.content.includes(kw)) ||
+ (p.category && p.category.includes(kw)) ||
+ (p.contact && p.contact.includes(kw))
+ )
+ }
+ }
setPosts(data)
setTotalPosts(todayStats.total || 0)
} catch { setPosts([]) }
@@ -62,6 +75,12 @@ export default function YichensBoard() {
useEffect(() => { if (todayStats.total > 0) fetchTodayCategory() }, [todayStats])
+ // 搜索关键词变化时重新获取数据
+ useEffect(() => {
+ setPage(1)
+ fetchPosts(1, '')
+ }, [searchKeyword])
+
const togglePost = id => setExpandedPosts(p => ({ ...p, [id]: !p[id] }))
const StatCard = ({ label, value, color, onClick }) => (
@@ -90,17 +109,36 @@ export default function YichensBoard() {
-
-
📊 今日分类统计
-
+
+
📊 今日分类统计
+
{todayCategory.map(cat => (
-
+
{cat.category} ({cat.count})
))}
+ {/* 搜索框 */}
+
+
+ { setSearchKeyword(e.target.value); setPage(1); fetchPosts(1, '') }}
+ style={{ flex: 1, padding: '10px 14px', borderRadius: 8, border: '1px solid #374151', background: '#1f2937', color: '#fff', fontSize: 13, outline: 'none' }}
+ />
+ { setSearchKeyword(''); setPage(1); fetchPosts(1, '') }}
+ style={{ padding: '10px 16px', borderRadius: 8, border: 'none', background: '#4b5563', color: '#fff', cursor: 'pointer', fontSize: 13 }}>
+ 清空
+
+
+ {searchKeyword &&
搜索: "{searchKeyword}",找到 {posts.length} 条结果
}
+
+
{[{key:'all',label:'全部'},{key:'deal',label:'出售'},{key:'want',label:'求购'},{key:'other',label:'其他'}].map(k => (
{ setPostTypeFilter(k.key==='other'?'other':k.key); setCategoryFilter(''); setPage(1); fetchPosts(1, '') }}
@@ -123,23 +161,6 @@ export default function YichensBoard() {
{loading ? 加载中...
: (
-
-
- 共 {totalPosts} 条帖子,{Math.ceil(totalPosts / 390)} 页,当前第 {page} 页
-
-
- {page > 1 ? (
- { const newPage = page - 1; setPage(newPage); fetchPosts(newPage, categoryFilter) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>上一页
- ) : (
- 上一页
- )}
- {posts.length >= 390 ? (
- { const newPage = page + 1; setPage(newPage); fetchPosts(newPage, categoryFilter) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>下一页
- ) : (
- 下一页
- )}
-
-
{posts.map(post => (
@@ -171,6 +192,25 @@ export default function YichensBoard() {
))}
+
+ {/* 分页按钮移到页面底部 */}
+
+
+ 共 {totalPosts} 条帖子,{Math.ceil(totalPosts / 390)} 页,当前第 {page} 页
+
+
+ {page > 1 ? (
+ { const newPage = page - 1; setPage(newPage); fetchPosts(newPage, categoryFilter) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>上一页
+ ) : (
+ 上一页
+ )}
+ {posts.length >= 390 ? (
+ { const newPage = page + 1; setPage(newPage); fetchPosts(newPage, categoryFilter) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>下一页
+ ) : (
+ 下一页
+ )}
+
+
)}