hookehuyr

feat(消息列表): 替换模拟数据为真实API接口获取

实现消息列表页面与后端API对接,包括初始化数据、加载更多和搜索功能
移除原有的模拟数据生成逻辑,改为从接口获取真实数据
添加错误处理和加载状态管理
...@@ -102,6 +102,8 @@ import TabBar from '@/components/TabBar.vue' ...@@ -102,6 +102,8 @@ import TabBar from '@/components/TabBar.vue'
102 import MessageDetail from '@/components/MessageDetail.vue' 102 import MessageDetail from '@/components/MessageDetail.vue'
103 import { $ } from '@tarojs/extend' 103 import { $ } from '@tarojs/extend'
104 import Taro from '@tarojs/taro' 104 import Taro from '@tarojs/taro'
105 +// 导入接口
106 +import { getMessagesListAPI } from '@/api/chat'
105 107
106 // 默认头像 108 // 默认头像
107 const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' 109 const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'
...@@ -116,8 +118,13 @@ const scrollTop = ref(0) ...@@ -116,8 +118,13 @@ const scrollTop = ref(0)
116 118
117 // 搜索值 119 // 搜索值
118 const searchValue = ref('') 120 const searchValue = ref('')
119 -const onBlurSearch = () => { 121 +const onBlurSearch = async () => {
120 console.warn(searchValue.value) 122 console.warn(searchValue.value)
123 + // 重置分页状态
124 + page.value = 1
125 + hasMore.value = true
126 + // 重新获取数据
127 + await initData()
121 } 128 }
122 // 当前激活的Tab 129 // 当前激活的Tab
123 const activeTab = ref('all') 130 const activeTab = ref('all')
...@@ -130,7 +137,7 @@ const pageSize = 10 ...@@ -130,7 +137,7 @@ const pageSize = 10
130 // 是否还有更多数据 137 // 是否还有更多数据
131 const hasMore = ref(true) 138 const hasMore = ref(true)
132 139
133 -// 模拟对话数据 140 +// 对话数据
134 const conversations = ref([]) 141 const conversations = ref([])
135 142
136 // 消息详情弹框相关 143 // 消息详情弹框相关
...@@ -141,27 +148,63 @@ const selectedConversation = ref(null) ...@@ -141,27 +148,63 @@ const selectedConversation = ref(null)
141 const mockMessages = ref([]) 148 const mockMessages = ref([])
142 149
143 // 初始化数据 150 // 初始化数据
144 -const initData = () => { 151 +const initData = async () => {
145 - const mockData = [] 152 + try {
146 - 153 + loading.value = true
147 - // 生成更多初始数据确保可以滚动 154 +
148 - for (let i = 1; i <= 15; i++) { 155 + // 根据当前tab获取对应的消息类型和状态
149 - const types = ['chat', 'system'] 156 + const params = {
150 - const type = types[i % 2] 157 + page: 0,
151 - 158 + limit: pageSize
152 - mockData.push({ 159 + }
153 - id: i, 160 +
154 - name: type === 'system' ? '系统通知' : `用户${i}`, 161 + // 根据activeTab设置过滤参数
155 - avatar: type === 'chat' ? `https://randomuser.me/api/portraits/men/${(i % 50) + 1}.jpg` : '', 162 + if (activeTab.value === 'unread') {
156 - icon: type === 'system' ? markRaw(Notice) : null, 163 + params.status = 3 // 未读
157 - lastMessage: type === 'system' ? '您有新的系统通知' : `这是第${i}条消息内容`, 164 + } else if (activeTab.value === 'system') {
158 - time: i <= 5 ? `${i * 5}分钟前` : i <= 10 ? `${i}小时前` : `${i - 10}天前`, 165 + params.type = 'system' // 系统消息
159 - unread: Math.random() > 0.5, 166 + }
160 - type: type 167 +
161 - }) 168 + // 如果有搜索关键词
169 + if (searchValue.value) {
170 + params.keyword = searchValue.value
162 } 171 }
163 172
164 - conversations.value = mockData 173 + const response = await getMessagesListAPI(params)
174 +
175 + if (response.code && response.data && response.data.list) {
176 + // 转换API数据格式为组件需要的格式
177 + const transformedData = response.data.list.map(item => ({
178 + id: item.id,
179 + name: item.type === 'system' ? '系统通知' : (item.partner_nickname || '未知用户'),
180 + avatar: item.type === 'chat' ? (item.partner_avatar_url || defaultAvatar) : '',
181 + icon: item.type === 'system' ? markRaw(Notice) : null,
182 + lastMessage: item.note || '',
183 + time: item.created_time_desc || '',
184 + unread: item.status === 3, // 3=未读,5=已读
185 + type: item.type,
186 + create_time: item.create_time
187 + }))
188 +
189 + conversations.value = transformedData
190 +
191 + // 判断是否还有更多数据
192 + hasMore.value = transformedData.length === pageSize
193 + } else {
194 + conversations.value = []
195 + hasMore.value = false
196 + }
197 + } catch (error) {
198 + console.error('获取消息列表失败:', error)
199 + Taro.showToast({
200 + title: '获取消息失败',
201 + icon: 'error'
202 + })
203 + conversations.value = []
204 + hasMore.value = false
205 + } finally {
206 + loading.value = false
207 + }
165 } 208 }
166 209
167 // 过滤后的对话列表 210 // 过滤后的对话列表
...@@ -187,7 +230,7 @@ const filteredConversations = computed(() => { ...@@ -187,7 +230,7 @@ const filteredConversations = computed(() => {
187 }) 230 })
188 231
189 // Tab点击事件 232 // Tab点击事件
190 -const setActiveTab = (tabKey) => { 233 +const setActiveTab = async (tabKey) => {
191 if (activeTab.value === tabKey) return; 234 if (activeTab.value === tabKey) return;
192 235
193 // 添加淡出效果 236 // 添加淡出效果
...@@ -197,7 +240,7 @@ const setActiveTab = (tabKey) => { ...@@ -197,7 +240,7 @@ const setActiveTab = (tabKey) => {
197 conversationList.style.transform = 'translateY(10rpx)'; 240 conversationList.style.transform = 'translateY(10rpx)';
198 } 241 }
199 242
200 - setTimeout(() => { 243 + setTimeout(async () => {
201 activeTab.value = tabKey; 244 activeTab.value = tabKey;
202 // 重置搜索条件 245 // 重置搜索条件
203 searchValue.value = ''; 246 searchValue.value = '';
...@@ -211,8 +254,8 @@ const setActiveTab = (tabKey) => { ...@@ -211,8 +254,8 @@ const setActiveTab = (tabKey) => {
211 setTimeout(() => { 254 setTimeout(() => {
212 scrollTop.value = 0; // 重置到顶部 255 scrollTop.value = 0; // 重置到顶部
213 }, 50); 256 }, 50);
214 - // 重新初始化数据 257 + // 重新获取数据
215 - initData(); 258 + await initData();
216 259
217 // 添加淡入效果 260 // 添加淡入效果
218 setTimeout(() => { 261 setTimeout(() => {
...@@ -230,45 +273,63 @@ const loadMore = async () => { ...@@ -230,45 +273,63 @@ const loadMore = async () => {
230 return 273 return
231 } 274 }
232 275
276 + try {
233 loading.value = true 277 loading.value = true
234 278
235 - // 模拟API请求 279 + // 构建请求参数
236 - setTimeout(() => { 280 + const params = {
237 - const newData = generateMockData(page.value + 1) 281 + page: page.value,
282 + limit: pageSize
283 + }
284 +
285 + // 根据activeTab设置过滤参数
286 + if (activeTab.value === 'unread') {
287 + params.status = 3 // 未读
288 + } else if (activeTab.value === 'system') {
289 + params.type = 'system' // 系统消息
290 + }
238 291
239 - if (newData.length > 0) { 292 + // 如果有搜索关键词
240 - conversations.value.push(...newData) 293 + if (searchValue.value) {
294 + params.keyword = searchValue.value
295 + }
296 +
297 + const response = await getMessagesListAPI(params)
298 +
299 + if (response.code && response.data && response.data.list) {
300 + // 转换API数据格式
301 + const transformedData = response.data.list.map(item => ({
302 + id: item.id,
303 + name: item.type === 'system' ? '系统通知' : (item.partner_nickname || '未知用户'),
304 + avatar: item.type === 'chat' ? (item.partner_avatar_url || defaultAvatar) : '',
305 + icon: item.type === 'system' ? markRaw(Notice) : null,
306 + lastMessage: item.note || '',
307 + time: item.created_time_desc || '',
308 + unread: item.status === 3, // 3=未读,5=已读
309 + type: item.type,
310 + create_time: item.create_time
311 + }))
312 +
313 + if (transformedData.length > 0) {
314 + conversations.value.push(...transformedData)
241 page.value++ 315 page.value++
316 + // 判断是否还有更多数据
317 + hasMore.value = transformedData.length === pageSize
242 } else { 318 } else {
243 hasMore.value = false 319 hasMore.value = false
244 } 320 }
321 + } else {
322 + hasMore.value = false
323 + }
324 + } catch (error) {
325 + console.error('加载更多消息失败:', error)
326 + hasMore.value = false
327 + } finally {
245 loading.value = false 328 loading.value = false
246 - }, 1000) 329 + }
247 -
248 - console.warn('loadMore', page.value, hasMore.value, loading.value);
249 } 330 }
250 331
251 -// 生成模拟数据
252 -const generateMockData = (pageNum) => {
253 - if (pageNum > 3) return [] // 模拟只有3页数据
254 -
255 - const mockData = []
256 - const startId = (pageNum - 1) * pageSize + conversations.value.length + 1
257 -
258 - for (let i = 0; i < pageSize; i++) {
259 - mockData.push({
260 - id: startId + i,
261 - name: `用户${startId + i}`,
262 - avatar: 'https://randomuser.me/api/portraits/men/32.jpg',
263 - lastMessage: `这是第${startId + i}条消息`,
264 - time: `${Math.floor(Math.random() * 24)}小时前`,
265 - unread: Math.random() > 0.5,
266 - type: 'chat'
267 - })
268 - }
269 332
270 - return mockData
271 -}
272 333
273 // 点击对话 - 显示消息详情弹框 334 // 点击对话 - 显示消息详情弹框
274 const onConversationClick = (conversation) => { 335 const onConversationClick = (conversation) => {
...@@ -317,7 +378,7 @@ const handleSendMessage = (data) => { ...@@ -317,7 +378,7 @@ const handleSendMessage = (data) => {
317 } 378 }
318 379
319 // 页面加载时初始化数据 380 // 页面加载时初始化数据
320 -onMounted(() => { 381 +onMounted(async () => {
321 // 设置滚动列表可视高度 382 // 设置滚动列表可视高度
322 const windowHeight = wx.getWindowInfo().windowHeight; 383 const windowHeight = wx.getWindowInfo().windowHeight;
323 setTimeout(async () => { 384 setTimeout(async () => {
...@@ -327,7 +388,7 @@ onMounted(() => { ...@@ -327,7 +388,7 @@ onMounted(() => {
327 height: windowHeight - headerHeight - navHeight - 70 + 'px' 388 height: windowHeight - headerHeight - navHeight - 70 + 'px'
328 } 389 }
329 }, 500); 390 }, 500);
330 - initData() 391 + await initData()
331 }) 392 })
332 </script> 393 </script>
333 394
......