v1.2.73 - 全局搜索后端支持
This commit is contained in:
parent
e5a5a2c48c
commit
e5a6a5928e
|
|
@ -111,9 +111,10 @@ def get_posts(
|
||||||
offset: int = Query(0, ge=0),
|
offset: int = Query(0, ge=0),
|
||||||
category: Optional[str] = None,
|
category: Optional[str] = None,
|
||||||
post_type: Optional[str] = None,
|
post_type: Optional[str] = None,
|
||||||
|
keyword: Optional[str] = None,
|
||||||
db: Session = Depends(get_coolbot_db)
|
db: Session = Depends(get_coolbot_db)
|
||||||
):
|
):
|
||||||
"""获取帖子列表"""
|
"""获取帖子列表 - 支持全局搜索"""
|
||||||
query = """
|
query = """
|
||||||
SELECT post_id, title, content, category, post_type, price,
|
SELECT post_id, title, content, category, post_type, price,
|
||||||
author_username, post_time, reply_count, view_count, url
|
author_username, post_time, reply_count, view_count, url
|
||||||
|
|
@ -130,6 +131,11 @@ def get_posts(
|
||||||
query += " AND post_type = :post_type"
|
query += " AND post_type = :post_type"
|
||||||
params["post_type"] = post_type
|
params["post_type"] = post_type
|
||||||
|
|
||||||
|
# 全局搜索 - 在标题、内容、分类、联系方式中搜索
|
||||||
|
if keyword:
|
||||||
|
query += " AND (title ILIKE :keyword OR content ILIKE :keyword OR category ILIKE :keyword OR author_username ILIKE :keyword)"
|
||||||
|
params["keyword"] = f"%{keyword}%"
|
||||||
|
|
||||||
query += " ORDER BY post_time DESC LIMIT :limit OFFSET :offset"
|
query += " ORDER BY post_time DESC LIMIT :limit OFFSET :offset"
|
||||||
|
|
||||||
results = db.execute(text(query), params).fetchall()
|
results = db.execute(text(query), params).fetchall()
|
||||||
|
|
|
||||||
|
|
@ -35,16 +35,18 @@ export default function YichensBoard() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchPosts = async (p, cat) => {
|
const fetchPosts = async (p, cat, kw) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
const currentPage = p !== undefined ? p : page
|
const currentPage = p !== undefined ? p : page
|
||||||
const currentCat = cat !== undefined ? cat : categoryFilter
|
const currentCat = cat !== undefined ? cat : categoryFilter
|
||||||
|
const searchKw = kw !== undefined ? kw : searchKeyword
|
||||||
|
|
||||||
let url = '/api/yichens/posts?limit=50&offset=' + ((currentPage - 1) * 390)
|
let url = '/api/yichens/posts?limit=390&offset=' + ((currentPage - 1) * 390)
|
||||||
if (postTypeFilter === 'deal') url += '&post_type=deal'
|
if (postTypeFilter === 'deal') url += '&post_type=deal'
|
||||||
else if (postTypeFilter === 'want') url += '&post_type=want'
|
else if (postTypeFilter === 'want') url += '&post_type=want'
|
||||||
else if (postTypeFilter === 'other') url += '&post_type=normal'
|
else if (postTypeFilter === 'other') url += '&post_type=normal'
|
||||||
|
if (searchKw && searchKw.trim()) url += '&keyword=' + encodeURIComponent(searchKw.trim())
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('YichensBoard: 请求 posts', url)
|
console.log('YichensBoard: 请求 posts', url)
|
||||||
|
|
@ -63,17 +65,6 @@ export default function YichensBoard() {
|
||||||
data = data.filter(p => p.category && !p.category.includes('龙') && !p.category.includes('纪念钞') && !p.category.includes('蛇') && !p.category.includes('马'))
|
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)
|
setPosts(data)
|
||||||
setTotalPosts(todayStats.total || 0)
|
setTotalPosts(todayStats.total || 0)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
@ -218,16 +209,16 @@ export default function YichensBoard() {
|
||||||
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 16px', background: '#1e293b', borderRadius: 12, marginTop: 16 }}>
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 16px', background: '#1e293b', borderRadius: 12, marginTop: 16 }}>
|
||||||
<div style={{ color: '#9ca3af', fontSize: 12 }}>
|
<div style={{ color: '#9ca3af', fontSize: 12 }}>
|
||||||
共 {totalPosts} 条帖子,{Math.ceil(totalPosts / 50)} 页,当前第 {page} 页
|
共 {totalPosts} 条帖子,{Math.ceil(totalPosts / 390)} 页,当前第 {page} 页
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex', gap: 8 }}>
|
<div style={{ display: 'flex', gap: 8 }}>
|
||||||
{page > 1 ? (
|
{page > 1 ? (
|
||||||
<button onClick={() => { 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 }}>上一页</button>
|
<button onClick={() => { const newPage = page - 1; setPage(newPage); fetchPosts(newPage, categoryFilter, searchKeyword) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>上一页</button>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ padding: '6px 12px', borderRadius: 6, background: '#374151', color: '#6b7280', fontSize: 12 }}>上一页</span>
|
<span style={{ padding: '6px 12px', borderRadius: 6, background: '#374151', color: '#6b7280', fontSize: 12 }}>上一页</span>
|
||||||
)}
|
)}
|
||||||
{posts.length >= 50 ? (
|
{posts.length >= 390 ? (
|
||||||
<button onClick={() => { 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 }}>下一页</button>
|
<button onClick={() => { const newPage = page + 1; setPage(newPage); fetchPosts(newPage, categoryFilter, searchKeyword) }} style={{ padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3b82f6', color: '#fff', cursor: 'pointer', fontSize: 12 }}>下一页</button>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ padding: '6px 12px', borderRadius: 6, background: '#374151', color: '#6b7280', fontSize: 12 }}>下一页</span>
|
<span style={{ padding: '6px 12px', borderRadius: 6, background: '#374151', color: '#6b7280', fontSize: 12 }}>下一页</span>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue