blob: c786ac7d1874248dc67727fd46d31ee2836b1732 [file] [log] [blame]
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +08001// search.tsx
阳菜,放晴!33a0d332025-06-08 22:39:42 +08002import React, { useState, useEffect, } from 'react';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +08003import styles from './search.module.css';
阳菜,放晴!33a0d332025-06-08 22:39:42 +08004import { useLocation, useSearchParams } from "react-router-dom";
阳菜,放晴!2f987042025-06-08 14:54:50 +08005import { getSearch } from '@/api/search'
阳菜,放晴!33a0d332025-06-08 22:39:42 +08006import request from '@/utils/request'; // 路径按你项目调整
7import { useApi } from '@/hooks/request';
8import { debounce } from 'lodash';
9// import { getTagsByMainTag } from '@/utils/common';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080010
11interface PostItem {
12 postId: number;
13 userId: number;
14 postTitle: string;
15 postContent: string;
16 createdAt: number;
17 postType: string;
18 viewCount: number;
19 hotScore: number;
20 lastCalculated: number;
21 tags?: number[];
22}
23
阳菜,放晴!77743f42025-06-06 23:04:08 +080024const tagMap: Record<string, Record<number, string>> = {
25 Game: {
阳菜,放晴!33a0d332025-06-08 22:39:42 +080026 1: "android",
27 2: "mac",
28 3: "pc",
29 4: "ios",
30 5: "other",
31 6: "action",
32 7: "adventure",
33 8: "leisure",
34 9: "riddle",
35 10: "sport",
36 11: "strategy",
37 12: "table",
阳菜,放晴!77743f42025-06-06 23:04:08 +080038 },
39 video: {
阳菜,放晴!33a0d332025-06-08 22:39:42 +080040 21: "chinese",
41 22: "America",
42 23: "Japan",
43 24: "Koera",
44 25: "Europe",
45 26: "other",
46 27: "Short",
47 28: "plot",
48 29: "comedy",
49 30: "love",
50 31: "action",
51 32: "terror",
52 33: "science fiction",
53 34: "commit a crime",
54 35: "Thriller",
阳菜,放晴!77743f42025-06-06 23:04:08 +080055 },
56 music: {
阳菜,放晴!33a0d332025-06-08 22:39:42 +080057 41: "chinese",
58 42: "America",
59 43: "Japan",
60 44: "Korea",
61 45: "Europe",
62 46: "other",
63 47: "rap",
64 48: "Electric sound",
65 49: "Guofeng",
66 50: "motion",
67 51: "ballad",
68 52: "Rock and roll",
69 53: "classical",
阳菜,放晴!77743f42025-06-06 23:04:08 +080070 },
71 software: {
阳菜,放晴!33a0d332025-06-08 22:39:42 +080072 61: "android",
73 62: "mac",
74 63: "pc",
75 64: "ios",
76 65: "other",
77 66: "life",
78 67: "shopping",
79 68: "video",
80 69: "music",
81 70: "read",
82 71: "system",
阳菜,放晴!77743f42025-06-06 23:04:08 +080083 },
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080084};
85
阳菜,放晴!33a0d332025-06-08 22:39:42 +080086const getTagsByMainTag = (mainTag: string): Record<number, string> => {
87 if (mainTag === "all") return {};
88 return tagMap[mainTag] || {};
89};
90
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080091const SearchPage: React.FC = () => {
阳菜,放晴!33a0d332025-06-08 22:39:42 +080092 const [searchParams] = useSearchParams()
93
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080094 const [selectedPostType, setSelectedPostType] = useState<string>('all');
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080095 const [selectedTags, setSelectedTags] = useState<number[]>([]);
阳菜,放晴!33a0d332025-06-08 22:39:42 +080096 const [postsRes, setPosts] = useState<PostItem[]>([]);
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080097
阳菜,放晴!33a0d332025-06-08 22:39:42 +080098 const keyword = searchParams.get('keyword') || '';
99
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800100 useEffect(() => {
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800101 if (keyword) {
102 handleSearch({
103 keyword,
104 author: '',
105 tags: []
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800106 });
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800107 }
阳菜,放晴!2f987042025-06-08 14:54:50 +0800108 }, [keyword]);
109
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800110
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800111 const handleSearch = async (params:{
112 keyword: string;
113 author: string;
114 tags: number[];
115 }) => {
116 try {
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800117
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800118 let queryParams: string = '';
119 if(params.keyword.trim() !== '') {
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800120 queryParams += "keyword";
121 queryParams += "=";
122 queryParams += params.keyword.trim();
123 queryParams += "&";
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800124 }
125 queryParams += "author";
126 queryParams += "&";
127 if (params.tags.length > 0 || params.author !== '') {
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800128 queryParams += "tags";
129 queryParams += "=";
130 if(params.tags.length >0){
131 queryParams += params.author;
132 queryParams += ",";
133 queryParams += params.tags.join(',');
134 }else{
135 queryParams += params.author;
136 }
137
138 }else{
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800139 queryParams += "tags";
140 }
141
142 console.log("queryParams",queryParams);
143 const url = `${getSearch}?${queryParams}`;
144 const res = await request.get(url);
145 console.log("url:",url);
146 console.log("res:",res);
147 setPosts(res);
148 } catch (error) {
149 console.error('获取帖子搜索错误', error);
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800150 }
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800151 };
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800152
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800153
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800154 const handleFilterClick = () => {
155 // 分区处理:如果选择"all",则author为空字符串
156 const author = selectedPostType === 'all' ? '' : selectedPostType;
157
158 handleSearch({
159 keyword,
160 author,
161 tags: selectedTags
162 });
163 };
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800164
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800165 const handlePostTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
166 const value = e.target.value;
167 setSelectedPostType(value);
168 // 切换分区时清空已选标签
169 setSelectedTags([]);
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800170 };
171
172 return (
阳菜,放晴!2f987042025-06-08 14:54:50 +0800173 <div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800174 <div className={styles.secondaryHeader}>
175 <div className={styles.leftSection}>
176 <select
177 value={selectedPostType}
178 onChange={(e) => setSelectedPostType(e.target.value)}
179 className={styles.selectBox}
180 >
181 <option value="all">所有分区</option>
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800182 <option value="20">影视</option>
183 <option value="40">音乐</option>
184 <option value="0">游戏</option>
185 <option value="60">软件</option>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800186 </select>
187
188 <select
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800189 className={styles.selectBox}
190 >
191 <option value="">所有评分</option>
192 <option value="1">1星及以上</option>
193 <option value="2">2星及以上</option>
194 <option value="3">3星及以上</option>
195 <option value="4">4星及以上</option>
196 <option value="5">5星</option>
197 </select>
198 </div>
199
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800200 <div className={styles.centerSection}>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800201 <div className={styles.tagFilters}>
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800202 {selectedPostType !== "all" &&
203 Object.entries(getTagsByMainTag(selectedPostType)).map(([tagId, tagName]) => {
204 const tagIdNum = Number(tagId);
205 return (
206 <label key={tagId}>
207 <input
208 type="checkbox"
209 value={tagId}
210 checked={selectedTags.includes(tagIdNum)}
211 onChange={(e) => {
212 const value = Number(e.target.value);
213 setSelectedTags((prev) =>
214 prev.includes(value)
215 ? prev.filter((t) => t !== value)
216 : [...prev, value]
217 );
218 }}
219 />
220 {tagName}
221 </label>
222 );
223 })
224 }
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800225 </div>
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800226 </div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800227
228 <div className={styles.rightSection}>
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800229 <button className={styles.filterButton} onClick={handleFilterClick}>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800230 筛选
231 </button>
232 </div>
233 </div>
234
阳菜,放晴!2f987042025-06-08 14:54:50 +0800235 <div className={styles.results}>
阳菜,放晴!33a0d332025-06-08 22:39:42 +0800236 {postsRes?.length === 0 ? (
237 <p>暂无搜索结果</p>
238 ) : (
239 <ul className={styles.resultList}>
240 {postsRes?.map((post) => (
241 <li key={post.postId} className={styles.resultItem}>
242 <h3>{post.postTitle || '无标题'}</h3>
243 <p>{post.postContent || '无内容'}</p>
244 <p>类型:{post.postType || '未知'} | 观看次数:{post.viewCount}</p>
245 </li>
246 ))}
247 </ul>
248 )}
阳菜,放晴!2f987042025-06-08 14:54:50 +0800249 </div>
阳菜,放晴!2f987042025-06-08 14:54:50 +0800250 </div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800251 );
252};
253
254export default SearchPage;