blob: bf252c519b6159bf27233abd18e4b449e5a09734 [file] [log] [blame]
// search.tsx
import React, { useState, useEffect } from 'react';
import styles from './search.module.css';
import { useLocation } from "react-router-dom";
import { getSearch } from '@/api/search'
interface PostItem {
postId: number;
userId: number;
postTitle: string;
postContent: string;
createdAt: number;
postType: string;
viewCount: number;
hotScore: number;
lastCalculated: number;
tags?: number[];
}
const tagMap: Record<string, Record<number, string>> = {
Game: {
0: "android",
1: "mac",
2: "pc",
3: "ios",
4: "other",
5: "action",
6: "adventure",
7: "leisure",
8: "riddle",
9: "sport",
10: "strategy",
11: "table",
},
video: {
20: "chinese",
21: "America",
22: "Japan",
23: "Koera",
24: "Europe",
25: "other",
26: "Short",
27: "plot",
28: "comedy",
29: "love",
30: "action",
31: "terror",
32: "science fiction",
33: "commit a crime",
34: "Thriller",
},
music: {
40: "chinese",
41: "America",
42: "Japan",
43: "Korea",
44: "Europe",
45: "other",
46: "rap",
47: "Electric sound",
48: "Guofeng",
49: "motion",
50: "ballad",
51: "Rock and roll",
52: "classical",
},
software: {
60: "android",
61: "mac",
62: "pc",
63: "ios",
64: "other",
65: "life",
66: "shopping",
67: "video",
68: "music",
69: "read",
70: "system",
},
};
const SearchPage: React.FC = () => {
const [posts, setPosts] = useState<PostItem[]>([]);
const [filteredPosts, setFilteredPosts] = useState<PostItem[]>([]);
const [selectedPostType, setSelectedPostType] = useState<string>('all');
const [selectedRating, setSelectedRating] = useState<number | null>(null);
const [selectedTags, setSelectedTags] = useState<number[]>([]);
const location = useLocation();
const params = new URLSearchParams(location.search);
const keyword = params.get("keyword");
const getTagsForPostType = (postType: string) => {
return tagMap[postType] || {};
};
useEffect(() => {
if (!keyword) return;
const requestBody = {
keyword,
tags: [] // 可以为空
};
console.log("请求发送:", getSearch, requestBody);
fetch(getSearch, {
method: 'Get',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(res => res.json())
.then((res) => {
const data: PostItem[] = res.data;
setPosts(data);
setFilteredPosts(data);
})
.catch((error) => {
console.error('搜索请求失败:', error);
});
}, [keyword]);
const applyFilters = () => {
let filtered = posts;
if (selectedPostType !== 'all') {
filtered = filtered.filter((post) => post.postType === selectedPostType);
}
if (selectedRating !== null) {
filtered = filtered.filter((post) => post.hotScore >= selectedRating);
}
if (selectedTags.length > 0) {
filtered = filtered.filter((post) =>
post.tags?.some((tag) => selectedTags.includes(tag))
);
}
setFilteredPosts(filtered);
};
return (
<div>
<div className={styles.secondaryHeader}>
<div className={styles.leftSection}>
<select
value={selectedPostType}
onChange={(e) => setSelectedPostType(e.target.value)}
className={styles.selectBox}
>
<option value="all">所有分区</option>
<option value="video">影视</option>
<option value="music">音乐</option>
<option value="Game">游戏</option>
<option value="software">软件</option>
</select>
<select
value={selectedRating || ''}
onChange={(e) =>
setSelectedRating(e.target.value ? Number(e.target.value) : null)
}
className={styles.selectBox}
>
<option value="">所有评分</option>
<option value="1">1星及以上</option>
<option value="2">2星及以上</option>
<option value="3">3星及以上</option>
<option value="4">4星及以上</option>
<option value="5">5星</option>
</select>
</div>
<div className={styles.centerSection}>
<div className={styles.tagFilters}>
{Object.entries(getTagsForPostType(selectedPostType)).map(([tagId, tagName]) => (
<label key={tagId}>
<input
type="checkbox"
value={tagId}
checked={selectedTags.includes(Number(tagId))}
onChange={(e) => {
const value = Number(e.target.value);
setSelectedTags((prev) =>
prev.includes(value)
? prev.filter((t) => t !== value)
: [...prev, value]
);
}}
/>
{tagName}
</label>
))}
</div>
</div>
<div className={styles.rightSection}>
<button className={styles.filterButton} onClick={applyFilters}>
筛选
</button>
</div>
</div>
<div className={styles.results}>
{filteredPosts.length === 0 ? (
<p>暂无搜索结果</p>
) : (
<ul className={styles.resultList}>
{filteredPosts.map((post) => (
<li key={post.postId} className={styles.resultItem}>
<h3>{post.postTitle || '无标题'}</h3>
<p>{post.postContent || '无内容'}</p>
<p>类型:{post.postType || '未知'} | 热度评分:{post.hotScore}</p>
</li>
))}
</ul>
)}
</div>
</div>
);
};
export default SearchPage;