返回 AiToEarn
comment.ts
根目录 / project / aitoearn-web / src / store / plugin / plats / xhs / comment.ts
1 /**
2 * 小红书评论功能模块
3 */
4
5 import type {
6 CommentItem,
7 CommentListParams,
8 CommentListResult,
9 CommentUser,
10 SubCommentListParams,
11 } from '../types'
12 import type {
13 XhsCommentItem,
14 XhsCommentListResponse,
15 XhsCommentUserInfo,
16 XhsSubCommentItem,
17 XhsSubCommentListResponse,
18 } from './types'
19
20 // ============================================================================
21 // 数据转换函数
22 // ============================================================================
23
24 /**
25 * 转换小红书用户信息为统一格式
26 */
27 function transformUser(userInfo: XhsCommentUserInfo): CommentUser {
28 return {
29 id: userInfo.user_id,
30 nickname: userInfo.nickname,
31 avatar: userInfo.image,
32 xsecToken: userInfo.xsec_token,
33 }
34 }
35
36 /**
37 * 检查是否为作者
38 */
39 function checkIsAuthor(showTags: string[]): boolean {
40 return showTags?.includes('is_author') ?? false
41 }
42
43 /**
44 * 转换小红书子评论为统一格式
45 */
46 function transformSubComment(item: XhsSubCommentItem): CommentItem {
47 return {
48 id: item.id,
49 content: item.content,
50 createTime: item.create_time,
51 likeCount: Number.parseInt(item.like_count, 10) || 0,
52 user: transformUser(item.user_info),
53 ipLocation: item.ip_location,
54 isAuthor: checkIsAuthor(item.show_tags),
55 isLiked: item.liked,
56 // 子评论没有更深层的回复
57 replyCount: 0,
58 replies: [],
59 hasMoreReplies: false,
60 // 回复目标
61 replyTo: item.target_comment
62 ? {
63 id: item.target_comment.id,
64 user: transformUser(item.target_comment.user_info),
65 }
66 : undefined,
67 origin: item,
68 }
69 }
70
71 /**
72 * 转换小红书评论为统一格式
73 */
74 function transformComment(item: XhsCommentItem): CommentItem {
75 return {
76 id: item.id,
77 content: item.content,
78 createTime: item.create_time,
79 likeCount: Number.parseInt(item.like_count, 10) || 0,
80 user: transformUser(item.user_info),
81 ipLocation: item.ip_location,
82 isAuthor: checkIsAuthor(item.show_tags),
83 isLiked: item.liked,
84 // 子评论相关
85 replyCount: Number.parseInt(item.sub_comment_count, 10) || 0,
86 replies: (item.sub_comments || []).map(transformSubComment),
87 replyCursor: item.sub_comment_cursor || '',
88 hasMoreReplies: item.sub_comment_has_more,
89 origin: item,
90 }
91 }
92
93 // ============================================================================
94 // API 调用函数
95 // ============================================================================
96
97 /**
98 * 获取评论列表
99 * @param params 评论列表请求参数
100 */
101 export async function getCommentList(params: CommentListParams): Promise<CommentListResult> {
102 // 检查插件
103 if (!window.AIToEarnPlugin) {
104 return {
105 success: false,
106 message: '插件未安装或未就绪',
107 comments: [],
108 cursor: '',
109 hasMore: false,
110 }
111 }
112
113 const { workId, cursor = '', count = 10, xsecToken = '' } = params
114
115 try {
116 // 构建请求参数
117 const queryParams = new URLSearchParams({
118 note_id: workId,
119 cursor,
120 top_comment_id: '',
121 image_formats: 'jpg,webp,avif',
122 })
123
124 // 如果有 xsec_token,添加到参数中
125 if (xsecToken) {
126 queryParams.set('xsec_token', xsecToken)
127 }
128
129 const response = await window.AIToEarnPlugin.xhsRequest<XhsCommentListResponse>({
130 path: `/api/sns/web/v2/comment/page?${queryParams.toString()}`,
131 method: 'GET',
132 })
133
134 if (!response.success || !response.data) {
135 return {
136 success: false,
137 message: response.msg || '获取评论列表失败',
138 comments: [],
139 cursor: '',
140 hasMore: false,
141 rawData: response,
142 }
143 }
144
145 // 转换数据格式
146 const comments = (response.data.comments || []).map(transformComment)
147
148 return {
149 success: true,
150 comments,
151 cursor: response.data.cursor || '',
152 hasMore: response.data.has_more,
153 rawData: response,
154 }
155 }
156 catch (error) {
157 return {
158 success: false,
159 message: error instanceof Error ? error.message : '请求失败',
160 comments: [],
161 cursor: '',
162 hasMore: false,
163 }
164 }
165 }
166
167 /**
168 * 获取子评论列表(查看更多回复)
169 * @param params 子评论列表请求参数
170 */
171 export async function getSubCommentList(params: SubCommentListParams): Promise<CommentListResult> {
172 // 检查插件
173 if (!window.AIToEarnPlugin) {
174 return {
175 success: false,
176 message: '插件未安装或未就绪',
177 comments: [],
178 cursor: '',
179 hasMore: false,
180 }
181 }
182
183 const { workId, rootCommentId, cursor = '', count = 10, xsecToken = '' } = params
184
185 try {
186 // 构建请求参数
187 const queryParams = new URLSearchParams({
188 note_id: workId,
189 root_comment_id: rootCommentId,
190 num: String(count),
191 cursor,
192 image_formats: 'jpg,webp,avif',
193 top_comment_id: '',
194 })
195
196 // 如果有 xsec_token,添加到参数中
197 if (xsecToken) {
198 queryParams.set('xsec_token', xsecToken)
199 }
200
201 const response = await window.AIToEarnPlugin.xhsRequest<XhsSubCommentListResponse>({
202 path: `/api/sns/web/v2/comment/sub/page?${queryParams.toString()}`,
203 method: 'GET',
204 })
205
206 if (!response.success || !response.data) {
207 return {
208 success: false,
209 message: response.msg || '获取子评论列表失败',
210 comments: [],
211 cursor: '',
212 hasMore: false,
213 rawData: response,
214 }
215 }
216
217 // 转换数据格式
218 const comments = (response.data.comments || []).map(transformSubComment)
219
220 return {
221 success: true,
222 comments,
223 cursor: response.data.cursor || '',
224 hasMore: response.data.has_more,
225 rawData: response,
226 }
227 }
228 catch (error) {
229 return {
230 success: false,
231 message: error instanceof Error ? error.message : '请求失败',
232 comments: [],
233 cursor: '',
234 hasMore: false,
235 }
236 }
237 }
238
238 lines TYPESCRIPT