956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 1 | // 搜索推荐算法相关的API接口 |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 2 | // 仅首页推荐和搜索使用 JWLLL 后端服务 |
| 3 | // 其他功能使用对应的后端服务 |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 4 | |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 5 | // JWLLL 后端服务 - 仅用于推荐和搜索 |
| 6 | const JWLLL_BASE_URL = 'http://10.126.59.25:5717' |
| 7 | // WZY 后端服务 - 用于帖子详情、点赞、评论等 |
22301008 | e25b4b0 | 2025-06-20 22:15:31 +0800 | [diff] [blame] | 8 | const WZY_BASE_URL = 'http://192.168.5.235:5714' |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 9 | |
| 10 | // 通用请求函数 |
| 11 | const request = async (url, options = {}) => { |
| 12 | try { |
| 13 | const response = await fetch(url, { |
| 14 | headers: { |
| 15 | 'Content-Type': 'application/json', |
| 16 | ...options.headers |
| 17 | }, |
| 18 | ...options |
| 19 | }) |
22301008 | e4acb92 | 2025-06-24 23:50:35 +0800 | [diff] [blame^] | 20 | |
| 21 | // 检查响应状态码 |
| 22 | if (!response.ok) { |
| 23 | let errorData |
| 24 | try { |
| 25 | errorData = await response.json() |
| 26 | } catch { |
| 27 | errorData = { error: `HTTP ${response.status}` } |
| 28 | } |
| 29 | throw new Error(errorData.error || `HTTP ${response.status}`) |
| 30 | } |
| 31 | |
| 32 | // 处理空响应(如204 No Content) |
| 33 | const contentType = response.headers.get('content-type') |
| 34 | if (contentType && contentType.includes('application/json')) { |
| 35 | return await response.json() |
| 36 | } else { |
| 37 | return {} // 返回空对象而不是尝试解析JSON |
| 38 | } |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 39 | } catch (error) { |
| 40 | console.error('API请求错误:', error) |
| 41 | throw error |
| 42 | } |
| 43 | } |
| 44 | |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 45 | // 搜索推荐API |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 46 | export const searchAPI = { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 47 | // ===== 推荐和搜索功能 - 使用 JWLLL 服务 ===== |
| 48 | |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 49 | // 搜索内容 |
| 50 | search: async (keyword, category = undefined) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 51 | return await request(`${JWLLL_BASE_URL}/search`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 52 | method: 'POST', |
| 53 | body: JSON.stringify({ keyword, category }) |
| 54 | }) |
| 55 | }, |
| 56 | |
| 57 | // 获取用户标签 |
| 58 | getUserTags: async (userId) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 59 | return await request(`${JWLLL_BASE_URL}/user_tags?user_id=${userId}`) |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 60 | }, |
| 61 | |
| 62 | // 标签推荐 |
| 63 | recommendByTags: async (userId, tags) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 64 | return await request(`${JWLLL_BASE_URL}/recommend_tags`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 65 | method: 'POST', |
| 66 | body: JSON.stringify({ user_id: userId, tags }) |
| 67 | }) |
| 68 | }, |
| 69 | |
| 70 | // 协同过滤推荐 |
| 71 | userBasedRecommend: async (userId, topN = 20) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 72 | return await request(`${JWLLL_BASE_URL}/user_based_recommend`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 73 | method: 'POST', |
| 74 | body: JSON.stringify({ user_id: userId, top_n: topN }) |
| 75 | }) |
| 76 | }, |
| 77 | |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 78 | // ===== 其他功能 - 使用 WZY 服务 ===== |
| 79 | |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 80 | // 获取帖子详情 |
| 81 | getPostDetail: async (postId) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 82 | return await request(`${WZY_BASE_URL}/posts/${postId}`) |
22301008 | e4acb92 | 2025-06-24 23:50:35 +0800 | [diff] [blame^] | 83 | }, // 点赞帖子 |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 84 | likePost: async (postId, userId) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 85 | return await request(`${WZY_BASE_URL}/posts/${postId}/like`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 86 | method: 'POST', |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 87 | body: JSON.stringify({ user_id: userId }) |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 88 | }) |
| 89 | }, |
| 90 | |
| 91 | // 取消点赞 |
| 92 | unlikePost: async (postId, userId) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 93 | return await request(`${WZY_BASE_URL}/posts/${postId}/like`, { |
| 94 | method: 'DELETE', |
| 95 | body: JSON.stringify({ user_id: userId }) |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 96 | }) |
| 97 | }, |
wu | 5a4acf7 | 2025-06-24 15:38:29 +0800 | [diff] [blame] | 98 | // 查看是否点赞 |
| 99 | hasLiked: async (postId, userId) => { |
| 100 | const res = await request( |
22301008 | e4acb92 | 2025-06-24 23:50:35 +0800 | [diff] [blame^] | 101 | `${WZY_BASE_URL}/posts/${postId}/like/status?user_id=${userId}`, |
wu | 5a4acf7 | 2025-06-24 15:38:29 +0800 | [diff] [blame] | 102 | { |
| 103 | method: 'GET' |
| 104 | } |
| 105 | ) |
| 106 | return res.liked |
| 107 | }, |
| 108 | |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 109 | // 添加评论 |
| 110 | addComment: async (postId, userId, content) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 111 | return await request(`${WZY_BASE_URL}/posts/${postId}/comments`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 112 | method: 'POST', |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 113 | body: JSON.stringify({ user_id: userId, content }) |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 114 | }) |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 115 | }, // 获取评论 |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 116 | getComments: async (postId) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 117 | const comments = await request(`${WZY_BASE_URL}/posts/${postId}/comments`) |
| 118 | // 适配数据格式,WZY服务返回数组,而前端期望 {comments: [...]} |
| 119 | // 同时转换字段名以适配前端期望的格式 |
| 120 | const adaptedComments = Array.isArray(comments) ? comments.map(comment => ({ |
| 121 | ...comment, |
| 122 | user_name: comment.user_name || `用户${comment.user_id}`, // 如果没有用户名,使用用户ID生成 |
| 123 | create_time: comment.created_at // 将 created_at 映射为 create_time |
| 124 | })) : [] |
| 125 | return { comments: adaptedComments } |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 126 | }, |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 127 | // 上传帖子 |
| 128 | uploadPost: async (postData) => { |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 129 | // 转换数据格式以适配 WZY 服务 |
| 130 | const payload = { |
| 131 | user_id: postData.user_id || 1, // 默认用户ID |
| 132 | title: postData.title, |
| 133 | content: postData.content, |
| 134 | type: postData.type || 'text', // 默认为文本类型 |
| 135 | media_urls: postData.media_files || [], |
| 136 | status: 'published' // 直接发布,不需要审核 |
| 137 | } |
| 138 | |
| 139 | const result = await request(`${WZY_BASE_URL}/posts`, { |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 140 | method: 'POST', |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 141 | body: JSON.stringify(payload) |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 142 | }) |
22301008 | ba662fe | 2025-06-20 18:10:20 +0800 | [diff] [blame] | 143 | |
| 144 | // 注意:WZY 服务目前不支持标签功能,tags 会被忽略 |
| 145 | // 如果需要标签功能,需要额外的API调用或使用支持标签的服务 |
| 146 | |
| 147 | return result |
956303669 | 80c1f27 | 2025-06-20 14:08:54 +0800 | [diff] [blame] | 148 | } |
| 149 | } |
| 150 | |
| 151 | export default searchAPI |