搜索实现
Change-Id: Ief2239e82cf46c8f05b3ded20708613ab6dcb1d3
diff --git a/src/views/search/search.tsx b/src/views/search/search.tsx
index bf252c5..aaccc99 100644
--- a/src/views/search/search.tsx
+++ b/src/views/search/search.tsx
@@ -1,8 +1,12 @@
// search.tsx
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, } from 'react';
import styles from './search.module.css';
-import { useLocation } from "react-router-dom";
+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;
@@ -19,130 +23,160 @@
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",
+ 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: {
- 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",
+ 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: {
- 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",
+ 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: {
- 60: "android",
- 61: "mac",
- 62: "pc",
- 63: "ios",
- 64: "other",
- 65: "life",
- 66: "shopping",
- 67: "video",
- 68: "music",
- 69: "read",
- 70: "system",
+ 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 [posts, setPosts] = useState<PostItem[]>([]);
- const [filteredPosts, setFilteredPosts] = useState<PostItem[]>([]);
+ const [searchParams] = useSearchParams()
+
const [selectedPostType, setSelectedPostType] = useState<string>('all');
- const [selectedRating, setSelectedRating] = useState<number | null>(null);
const [selectedTags, setSelectedTags] = useState<number[]>([]);
+ const [postsRes, setPosts] = useState<PostItem[]>([]);
- const location = useLocation();
- const params = new URLSearchParams(location.search);
- const keyword = params.get("keyword");
-
- const getTagsForPostType = (postType: string) => {
- return tagMap[postType] || {};
- };
-
+ const keyword = searchParams.get('keyword') || '';
+
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);
+ if (keyword) {
+ handleSearch({
+ keyword,
+ author: '',
+ tags: []
});
+ }
}, [keyword]);
- const applyFilters = () => {
- let filtered = posts;
+ const handleSearch = async (params:{
+ keyword: string;
+ author: string;
+ tags: number[];
+ }) => {
+ try {
- if (selectedPostType !== 'all') {
- filtered = filtered.filter((post) => post.postType === selectedPostType);
+ let queryParams: string = '';
+ if(params.keyword.trim() !== '') {
+ // queryParams.append('keyword',params.keyword.trim());
+ queryParams += "keyword";
+ queryParams += "=";
+ queryParams += params.keyword.trim();
+ queryParams += "&";
+ // queryParams.concat("keyword");
+ // queryParams.concat(params.keyword.trim());
+ // queryParams.concat("&");
+ }
+ queryParams += "author";
+ queryParams += "&";
+ if (params.tags.length > 0 || params.author !== '') {
+ // queryParams.append('tags', params.tags.join(','));
+ // queryParams.concat("tags");
+ // queryParams.concat(params.tags.join(','));
+ // queryParams.concat("&");
+ queryParams += "tags";
+ queryParams += "=";
+ if(params.tags.length >0){
+ queryParams += params.author;
+ queryParams += ",";
+ queryParams += params.tags.join(',');
+ }else{
+ queryParams += params.author;
+ }
+
+ }else{
+ // queryParams.append('tags', '');
+ // queryParams.concat("tags");
+ 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);
}
+ };
- 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))
- );
- }
+ const handleFilterClick = () => {
+ // 分区处理:如果选择"all",则author为空字符串
+ const author = selectedPostType === 'all' ? '' : selectedPostType;
+
+ handleSearch({
+ keyword,
+ author,
+ tags: selectedTags
+ });
+ };
- setFilteredPosts(filtered);
-
+ const handlePostTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
+ const value = e.target.value;
+ setSelectedPostType(value);
+ // 切换分区时清空已选标签
+ setSelectedTags([]);
};
return (
@@ -155,17 +189,13 @@
className={styles.selectBox}
>
<option value="all">所有分区</option>
- <option value="video">影视</option>
- <option value="music">音乐</option>
- <option value="Game">游戏</option>
- <option value="software">软件</option>
+ <option value="20">影视</option>
+ <option value="40">音乐</option>
+ <option value="0">游戏</option>
+ <option value="60">软件</option>
</select>
<select
- value={selectedRating || ''}
- onChange={(e) =>
- setSelectedRating(e.target.value ? Number(e.target.value) : null)
- }
className={styles.selectBox}
>
<option value="">所有评分</option>
@@ -177,56 +207,57 @@
</select>
</div>
- <div className={styles.centerSection}>
+ <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>
- ))}
+ {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>
<div className={styles.rightSection}>
- <button className={styles.filterButton} onClick={applyFilters}>
+ <button className={styles.filterButton} onClick={handleFilterClick}>
筛选
</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>
- )}
+ {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>
-
-
-
);
};