diff --git a/pages.json b/pages.json index e47d85e..8d0fb05 100644 --- a/pages.json +++ b/pages.json @@ -162,7 +162,7 @@ "pages": [ { "path": "list", - "style": { "navigationBarTitleText": "AI咨询记录", "disableScroll": true } + "style": { "navigationBarTitleText": "咨询记录", "disableScroll": true } }, { "path": "chat", diff --git a/pages/ai-consult/list.vue b/pages/ai-consult/list.vue index ea7768c..b7ac116 100644 --- a/pages/ai-consult/list.vue +++ b/pages/ai-consult/list.vue @@ -2,13 +2,17 @@ - - - {{ item.assistantName }}{{ statusText(item) }} + + + {{ item.assistantName }}{{ item.statusLabel }} + {{ item.sourceLabel }} 团队:{{ item.teamName || item.teamId || '-' }} 档案:{{ item.customerName || '-' }} 最近互动:{{ format(item.lastActiveTime) }} @@ -26,15 +30,17 @@ import { storeToRefs } from 'pinia'; import FullPage from '@/components/full-page.vue'; import EmptyData from '@/components/empty-data.vue'; const { openid } = storeToRefs(useAccountStore()); -const corpId = ref(''); const customerId = ref(''); const customers = ref([{ name: '全部档案', value: '' }]); +const corpId = ref(''); const customerId = ref(''); const source = ref(''); +const sources = [{ name: '全部咨询', value: '' }, { name: 'AI咨询', value: 'ai' }, { name: 'IM咨询', value: 'im' }]; +const customers = ref([{ name: '全部档案', value: '' }]); const list = ref([]); const page = ref(1); const pages = ref(0); const loading = ref(false); const format = value => value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '-'; -const statusText = item => item.status === 'active' ? '咨询中' : item.endReason === 'sensitive_word' ? '敏感词结束' : '已结束'; async function loadCustomers() { const res = await api('getMiniAppCustomers', { corpId: corpId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false); if (res?.success) customers.value = [customers.value[0], ...(res.data || []).map(item => ({ name: item.name || '未命名', value: item._id }))]; } -async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getAiConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), page: page.value, pageSize: 20 }, false); if (res?.success) { list.value = page.value === 1 ? res.list : [...list.value, ...res.list]; pages.value = res.pages || 0; } loading.value = false; } +async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getUnifiedConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), source: source.value, page: page.value, pageSize: 20 }, false); if (res?.success) { list.value = page.value === 1 ? res.list : [...list.value, ...res.list]; pages.value = res.pages || 0; } loading.value = false; } function selectCustomer(value) { if (customerId.value === value) return; customerId.value = value; load(true); } +function selectSource(value) { if (source.value === value) return; source.value = value; load(true); } function loadMore() { if (!loading.value && page.value < pages.value) { page.value += 1; load(); } } -function openChat(item) { uni.navigateTo({ url: `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item._id}` }); } +function openChat(item) { const url = item.source === 'im' ? `/pages/message/index?conversationID=GROUP${item.groupId}&groupID=${item.groupId}` : `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item.id}`; uni.navigateTo({ url }); } onLoad(async opts => { corpId.value = opts.corpId || ''; await loadCustomers(); await load(true); }); - + diff --git a/pages/home/consult.vue b/pages/home/consult.vue index 5103aa8..bc60135 100644 --- a/pages/home/consult.vue +++ b/pages/home/consult.vue @@ -49,7 +49,6 @@ const props = defineProps({ const { account } = storeToRefs(useAccount()); const consultantPopup = ref(null); const badgeMap = ref({}); -const aiConsultEnabled = ref(false); let loading = false; const consultItems = ref([ @@ -81,12 +80,6 @@ const consultItems = ref([ path: "/pages/rate/rate-list", badge: 'rate' }, - { - id: "aiConsultRecord", - label: "AI咨询记录", - icon: "/static/home/ai-consult-assistant.png", - path: "/pages/ai-consult/list", - }, ]); const hideMenus = computed(() => { const result = {}; @@ -94,7 +87,6 @@ const hideMenus = computed(() => { if (!(props.team && props.team.createSource === 'yzs')) { result.chat = true; } - if (!aiConsultEnabled.value) result.aiConsultRecord = true; return result; }) @@ -199,15 +191,8 @@ async function getBadgeCount() { loading = false; } -async function loadAiConsultPermission() { - if (!props.corpId) return; - const res = await api('getAiConsultPermission', { corpId: props.corpId }, false); - aiConsultEnabled.value = Boolean(res?.success && res?.data?.enabled); -} - watch(() => [props.customers, props.teamId, props.corpId], n => { getBadgeCount() - loadAiConsultPermission() }, { immediate: true }) defineExpose({ diff --git a/pages/message/message.vue b/pages/message/message.vue index 571b47d..2bded82 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -8,10 +8,11 @@ 加载中... - - + + {{ conversation.unreadCount > 99 ? "99+" : conversation.unreadCount @@ -21,13 +22,14 @@ - {{ conversation.teamName }} + {{ conversation.displayName || conversation.teamName }} {{ formatMessageTime(conversation.lastMessageTime) }} + AI咨询 咨询人 | {{ conversation.patientName }} @@ -72,6 +74,7 @@ import { mergeConversationWithGroupDetails } from "@/utils/conversation-merger.j import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; import { get } from "@/utils/cache"; import { normalizeCorpId } from "@/utils/api-base-config"; +import api from "@/utils/api"; import useGroupAvatars from "./hooks/use-group-avatars.js"; import GroupAvatar from "@/components/group-avatar.vue"; import { @@ -229,9 +232,10 @@ const loadConversationList = async () => { const result = await globalTimChatManager.getGroupList(); if (result && result.success && result.groupList) { // 合并后端群组详细信息(已包含格式化和排序) - conversationList.value = await mergeConversationWithGroupDetails( + const imConversations = await mergeConversationWithGroupDetails( result.groupList ); + conversationList.value = mergeConsultationList(imConversations); console.log( "群聊列表加载成功,共", conversationList.value.length, @@ -250,6 +254,46 @@ const loadConversationList = async () => { } }; +function mergeConsultationList(imConversations) { + const aiConversations = conversationList.value.filter((item) => item.source === "ai"); + return [...imConversations, ...aiConversations].sort( + (left, right) => (right.lastMessageTime || 0) - (left.lastMessageTime || 0) + ); +} + +const loadAiConsultationList = async () => { + const corpId = getCurrentTeamCorpId(); + const miniAppId = openid.value || account.value?.openid || ""; + if (!corpId || !miniAppId) return; + try { + const result = await api("getUnifiedConsultSessions", { + corpId, + miniAppId, + source: "ai", + page: 1, + pageSize: 100, + }, false); + if (!result?.success) return; + const imConversations = conversationList.value.filter((item) => item.source !== "ai"); + const aiConversations = (result.list || []).map((item) => ({ + source: "ai", + sessionId: item.id, + corpId: item.corpId, + displayName: item.assistantName || "AI咨询助理", + teamName: item.teamName || "", + patientName: item.customerName || "未命名患者", + lastMessage: item.statusLabel || "AI咨询", + lastMessageTime: item.lastActiveTime || 0, + unreadCount: 0, + })); + conversationList.value = [...imConversations, ...aiConversations].sort( + (left, right) => (right.lastMessageTime || 0) - (left.lastMessageTime || 0) + ); + } catch (error) { + console.log("加载AI咨询记录异常:", error.message); + } +}; + // 防抖更新定时器 let updateTimer = null; @@ -438,6 +482,13 @@ const formatMessageTime = (timestamp) => { const handleClickConversation = async (conversation) => { console.log("点击会话:", conversation); + if (conversation.source === "ai") { + uni.navigateTo({ + url: `/pages/ai-consult/chat?corpId=${conversation.corpId}&sessionId=${conversation.sessionId}`, + }); + return; + } + // 立即清除本地未读数显示 const conversationIndex = conversationList.value.findIndex( (conv) => conv.conversationID === conversation.conversationID @@ -480,11 +531,11 @@ const handleLoadMore = () => { // 下拉刷新 const handleRefresh = async () => { - if (!hasImCorpId.value) return; refreshing.value = true; try { - await loadConversationList(); + if (hasImCorpId.value) await loadConversationList(); + await loadAiConsultationList(); } finally { refreshing.value = false; } @@ -499,7 +550,8 @@ async function init() { console.log("IM初始化失败,继续加载列表"); } // 先加载初始会话列表 - await loadConversationList(); + if (imReady) await loadConversationList(); + await loadAiConsultationList(); // 再设置监听器,后续通过事件更新列表 setupConversationListener(); } catch (error) { @@ -580,9 +632,7 @@ onHide(() => { }); watch(hasImCorpId, (n, o) => { - if (n && !o) { - init(); - } + if (n || !o) init(); }, { immediate: true }) // 页面卸载 onUnmounted(() => { @@ -783,6 +833,16 @@ onUnmounted(() => { padding-bottom: 10rpx; } +.source-tag { + display: inline-block; + margin-right: 10rpx; + padding: 1rpx 8rpx; + border-radius: 6rpx; + color: #0877f1; + background: #e8f3ff; + font-size: 22rpx; +} + .subscribe-entry { position: fixed; right: 32rpx; diff --git a/utils/api.js b/utils/api.js index 1daba3e..c30e12c 100644 --- a/utils/api.js +++ b/utils/api.js @@ -23,6 +23,7 @@ const urlsConfig = { getAiConsultPermission: 'getAiConsultPermission', getAiConsultAssistants: 'getAiConsultAssistants', getAiConsultSessions: 'getAiConsultSessions', + getUnifiedConsultSessions: 'getUnifiedConsultSessions', getAiConsultSessionDetail: 'getAiConsultSessionDetail', openAiConsultSession: 'openAiConsultSession', sendAiConsultMessage: 'sendAiConsultMessage',