feat(消息列表): 替换模拟数据为真实API接口获取
实现消息列表页面与后端API对接,包括初始化数据、加载更多和搜索功能 移除原有的模拟数据生成逻辑,改为从接口获取真实数据 添加错误处理和加载状态管理
Showing
1 changed file
with
116 additions
and
55 deletions
| ... | @@ -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 | ... | ... |
-
Please register or login to post a comment