blob: c786ac7d1874248dc67727fd46d31ee2836b1732 [file] [log] [blame]
// search.tsx
import React, { useState, useEffect, } from 'react';
import styles from './search.module.css';
import { useLocation, useSearchParams } from "react-router-dom";
import { getSearch } from '@/api/search'
import request from '@/utils/request'; // 路径按你项目调整
import { useApi } from '@/hooks/request';
import { debounce } from 'lodash';
// import { getTagsByMainTag } from '@/utils/common';
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: {
1: "android",
2: "mac",
3: "pc",
4: "ios",
5: "other",
6: "action",
7: "adventure",
8: "leisure",
9: "riddle",
10: "sport",
11: "strategy",
12: "table",
},
video: {
21: "chinese",
22: "America",
23: "Japan",
24: "Koera",
25: "Europe",
26: "other",
27: "Short",
28: "plot",
29: "comedy",
30: "love",
31: "action",
32: "terror",
33: "science fiction",
34: "commit a crime",
35: "Thriller",
},
music: {
41: "chinese",
42: "America",
43: "Japan",
44: "Korea",
45: "Europe",
46: "other",
47: "rap",
48: "Electric sound",
49: "Guofeng",
50: "motion",
51: "ballad",
52: "Rock and roll",
53: "classical",
},
software: {
61: "android",
62: "mac",
63: "pc",
64: "ios",
65: "other",
66: "life",
67: "shopping",
68: "video",
69: "music",
70: "read",
71: "system",
},
};
const getTagsByMainTag = (mainTag: string): Record<number, string> => {
if (mainTag === "all") return {};
return tagMap[mainTag] || {};
};
const SearchPage: React.FC = () => {
const [searchParams] = useSearchParams()
const [selectedPostType, setSelectedPostType] = useState<string>('all');
const [selectedTags, setSelectedTags] = useState<number[]>([]);
const [postsRes, setPosts] = useState<PostItem[]>([]);
const keyword = searchParams.get('keyword') || '';
useEffect(() => {
if (keyword) {
handleSearch({
keyword,
author: '',
tags: []
});
}
}, [keyword]);
const handleSearch = async (params:{
keyword: string;
author: string;
tags: number[];
}) => {
try {
let queryParams: string = '';
if(params.keyword.trim() !== '') {
queryParams += "keyword";
queryParams += "=";
queryParams += params.keyword.trim();
queryParams += "&";
}
queryParams += "author";
queryParams += "&";
if (params.tags.length > 0 || params.author !== '') {
queryParams += "tags";
queryParams += "=";
if(params.tags.length >0){
queryParams += params.author;
queryParams += ",";
queryParams += params.tags.join(',');
}else{
queryParams += params.author;
}
}else{
queryParams += "tags";
}
console.log("queryParams",queryParams);
const url = `${getSearch}?${queryParams}`;
const res = await request.get(url);
console.log("url:",url);
console.log("res:",res);
setPosts(res);
} catch (error) {
console.error('获取帖子搜索错误', error);
}
};
const handleFilterClick = () => {
// 分区处理:如果选择"all",则author为空字符串
const author = selectedPostType === 'all' ? '' : selectedPostType;
handleSearch({
keyword,
author,
tags: selectedTags
});
};
const handlePostTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value;
setSelectedPostType(value);
// 切换分区时清空已选标签
setSelectedTags([]);
};
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="20">影视</option>
<option value="40">音乐</option>
<option value="0">游戏</option>
<option value="60">软件</option>
</select>
<select
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}>
{selectedPostType !== "all" &&
Object.entries(getTagsByMainTag(selectedPostType)).map(([tagId, tagName]) => {
const tagIdNum = Number(tagId);
return (
<label key={tagId}>
<input
type="checkbox"
value={tagId}
checked={selectedTags.includes(tagIdNum)}
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={handleFilterClick}>
筛选
</button>
</div>
</div>
<div className={styles.results}>
{postsRes?.length === 0 ? (
<p>暂无搜索结果</p>
) : (
<ul className={styles.resultList}>
{postsRes?.map((post) => (
<li key={post.postId} className={styles.resultItem}>
<h3>{post.postTitle || '无标题'}</h3>
<p>{post.postContent || '无内容'}</p>
<p>类型:{post.postType || '未知'} | 观看次数:{post.viewCount}</p>
</li>
))}
</ul>
)}
</div>
</div>
);
};
export default SearchPage;