ykt-wxapp/utils/conversation-merger.js
2026-01-29 10:43:06 +08:00

213 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 会话列表与群组详细信息合并工具
*
* 功能:
* 1. 从 conversationList 中提取所有 groupID
* 2. 调用后端 getGroupList 接口获取群组详细信息
* 3. 合并会话数据和患者信息
* 4. 过滤掉后端不存在的会话
*/
import api from "@/utils/api.js"
/**
* 合并会话列表和群组详细信息
*
* @param {Array} conversationList - 前端会话列表
* @param {Object} options - 可选参数
* @param {string} options.corpId - 企业ID可选
* @param {string} options.teamId - 团队ID可选
* @param {string} options.keyword - 搜索关键词(可选)
* @returns {Promise<Array>} 合并后的会话列表
*/
export async function mergeConversationWithGroupDetails(conversationList, options = {}) {
try {
// 1. 参数校验
if (!Array.isArray(conversationList) || conversationList.length === 0) {
console.log('会话列表为空,无需合并')
return []
}
// 2. 提取所有 groupID
const groupIds = conversationList
.map(conv => conv.groupID);
if (groupIds.length === 0) {
console.log('没有有效的 groupID无需合并')
return []
}
console.log('提取到的 groupID 列表:', groupIds)
// 3. 调用后端接口获取群组详细信息
const requestData = {
groupIds,
...options // 支持传入额外的查询参数corpId, teamId, keyword等
}
const response = await api('getGroupList', requestData)
// 4. 检查响应
if (!response || !response.success) {
console.error('获取群组详细信息失败:', response?.message || '未知错误')
return []
}
const groupDetailsMap = createGroupDetailsMap(response.data?.list || [])
console.log('获取到的群组详细信息数量:', Object.keys(groupDetailsMap).size)
// 5. 合并数据并过滤
const mergedList = conversationList
.map(conversation => mergeConversationData(conversation, groupDetailsMap))
.filter(item => item !== null) // 过滤掉后端不存在的会话
console.log('合并后的会话列表数量:', mergedList.length)
console.log('过滤掉的会话数量:', conversationList.length - mergedList.length)
// 6. 格式化并排序会话列表
const formattedList = mergedList
.map((group) => ({
conversationID: group.conversationID || `GROUP${group.groupID}`,
groupID: group.groupID,
name: group.patientName
? `${group.patientName}的问诊`
: group.name || "问诊群聊",
avatar: group.avatar || "/static/default-avatar.png",
lastMessage: group.lastMessage || "暂无消息",
lastMessageTime: group.lastMessageTime || Date.now(),
unreadCount: group.unreadCount || 0,
doctorId: group.doctorId,
patientName: group.patientName,
patientSex: group.patientSex,
patientAge: group.patientAge,
orderStatus: group.orderStatus,
}))
.sort((a, b) => b.lastMessageTime - a.lastMessageTime)
return formattedList
} catch (error) {
console.error('合并会话列表失败:', error)
// 发生错误时返回空数组,避免影响页面渲染
return []
}
}
/**
* 创建群组详细信息映射表
*
* @param {Array} groupDetailsList - 后端返回的群组详细信息列表
* @returns {Map} groupID -> 群组详细信息的映射
*/
function createGroupDetailsMap(groupDetailsList) {
const map = new Map()
groupDetailsList.forEach(groupDetail => {
if (groupDetail.groupId) {
map.set(groupDetail.groupId, groupDetail)
}
})
return map
}
/**
* 合并单个会话数据
*
* @param {Object} conversation - 前端会话数据
* @param {Map} groupDetailsMap - 群组详细信息映射表
* @returns {Object|null} 合并后的会话数据,如果后端不存在则返回 null
*/
function mergeConversationData(conversation, groupDetailsMap) {
const groupDetail = groupDetailsMap.get(conversation.groupID)
// 如果后端没有该群组信息,返回 null会被过滤掉
if (!groupDetail) {
console.log(`会话 ${conversation.groupID} 在后端不存在,已过滤`)
return null
}
// 合并数据
return {
// 保留原有的会话信息
...conversation,
// 合并后端的群组信息
_id: groupDetail._id,
corpId: groupDetail.corpId,
teamId: groupDetail.teamId,
customerId: groupDetail.customerId,
doctorId: groupDetail.doctorId,
patientId: groupDetail.patientId,
orderStatus: groupDetail.orderStatus,
// 合并患者信息(优先使用后端数据)
patientName: groupDetail.patientName || conversation.patientName,
patientSex: groupDetail.patient?.sex,
patientAge: groupDetail.patient?.age,
patientMobile: groupDetail.patient?.mobile,
patientAvatar: groupDetail.patient?.avatar || conversation.avatar,
// 合并团队信息
teamName: groupDetail.team?.name,
teamMemberList: groupDetail.team?.memberList,
teamDescription: groupDetail.team?.description,
// 时间信息
createdAt: groupDetail.createdAt,
updatedAt: groupDetail.updatedAt,
// 更新显示名称(使用后端的患者信息)
name: formatConversationName(groupDetail),
// 更新头像
avatar: groupDetail.patient?.avatar || conversation.avatar || '/static/default-avatar.png'
}
}
/**
* 格式化会话显示名称
*
* @param {Object} groupDetail - 群组详细信息
* @returns {string} 格式化后的名称
*/
function formatConversationName(groupDetail) {
const patientName = groupDetail.patientName || '患者'
const sex = groupDetail.patient?.sex === 1 ? '男' : groupDetail.patient?.sex === 2 ? '女' : ''
const age = groupDetail.patient?.age ? `${groupDetail.patient.age}` : ''
// 拼接名称:患者名 性别 年龄
const nameParts = [patientName, sex, age].filter(part => part)
const displayName = nameParts.join(' ')
return `${displayName}的问诊`
}
/**
* 批量合并会话列表(支持分页)
*
* @param {Array} conversationList - 前端会话列表
* @param {Object} options - 可选参数
* @param {number} options.batchSize - 每批处理的数量默认50
* @returns {Promise<Array>} 合并后的会话列表
*/
export async function mergeConversationWithGroupDetailsBatch(conversationList, options = {}) {
const { batchSize = 50, ...otherOptions } = options
if (!Array.isArray(conversationList) || conversationList.length === 0) {
return []
}
// 分批处理
const batches = []
for (let i = 0; i < conversationList.length; i += batchSize) {
batches.push(conversationList.slice(i, i + batchSize))
}
console.log(`会话列表分为 ${batches.length} 批处理,每批 ${batchSize}`)
// 并发处理所有批次
const results = await Promise.all(
batches.map(batch => mergeConversationWithGroupDetails(batch, otherOptions))
)
// 合并所有结果
return results.flat()
}