From b33c4357e85aa17a0035b5931b8319a300a228b2 Mon Sep 17 00:00:00 2001 From: wangdongbo <949818794@qq.com> Date: Wed, 28 Jan 2026 16:20:19 +0800 Subject: [PATCH] =?UTF-8?q?IM=20=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/message/article-detail.vue | 201 ---- pages/message/article-list.vue | 588 ----------- pages/message/common-phrases.vue | 1058 ------------------- pages/message/components/chat-input.vue | 100 +- pages/message/components/consult-apply.vue | 118 +++ pages/message/components/consult-cancel.vue | 6 +- pages/message/index.vue | 349 +++--- pages/message/message.vue | 2 +- pages/message/survey-list.vue | 446 -------- store/account.js | 4 +- 10 files changed, 285 insertions(+), 2587 deletions(-) delete mode 100644 pages/message/article-detail.vue delete mode 100644 pages/message/article-list.vue delete mode 100644 pages/message/common-phrases.vue create mode 100644 pages/message/components/consult-apply.vue delete mode 100644 pages/message/survey-list.vue diff --git a/pages/message/article-detail.vue b/pages/message/article-detail.vue deleted file mode 100644 index e6bfb76..0000000 --- a/pages/message/article-detail.vue +++ /dev/null @@ -1,201 +0,0 @@ - - - - - diff --git a/pages/message/article-list.vue b/pages/message/article-list.vue deleted file mode 100644 index 3c54a8f..0000000 --- a/pages/message/article-list.vue +++ /dev/null @@ -1,588 +0,0 @@ - - - - - diff --git a/pages/message/common-phrases.vue b/pages/message/common-phrases.vue deleted file mode 100644 index 3f5bde1..0000000 --- a/pages/message/common-phrases.vue +++ /dev/null @@ -1,1058 +0,0 @@ - - - - - diff --git a/pages/message/components/chat-input.vue b/pages/message/components/chat-input.vue index 72024ec..0bc6b81 100644 --- a/pages/message/components/chat-input.vue +++ b/pages/message/components/chat-input.vue @@ -79,7 +79,7 @@ const props = defineProps({ }); // Emits -const emit = defineEmits(["messageSent", "scrollToBottom", "endConsult"]); +const emit = defineEmits(["messageSent", "scrollToBottom"]); // 输入相关状态 const inputText = ref(""); @@ -153,22 +153,7 @@ const sendTextMessage = async () => { inputText.value = ""; }; -// 从常用语发送文本消息 -const sendTextMessageFromPhrase = async (content) => { - if (!content.trim()) return; - - await sendMessage("text", content); - - // 发送成功后滚动到底部 - nextTick(() => { - emit("scrollToBottom"); - }); -}; -// 暴露方法给父组件调用 -defineExpose({ - sendTextMessageFromPhrase -}); // 发送图片消息 const sendImageMessage = async (imageFile) => { @@ -338,91 +323,8 @@ const cancelRecord = () => { stopRecordUtil(recorderManager); }; -// 发送问卷调查消息 -const sendSurveyMessage = async () => { - const surveyMessage = createCustomMessage( - "survey", - { - content: "医生发送了问卷调查", - surveyTitle: "治疗效果评估", - surveyDescription: "您好,为了帮助了解您的病情变化,请您如实填写问卷。", - surveyMessage: "慢性病患者生活质量评估问卷", - estimatedTime: "约3-5分钟", - reward: "积分奖励10分", - note: "问卷内容涉及您的症状变化、用药情况等,请根据实际情况填写。", - }, - props.formatTime - ); - - await sendCustomMessage(surveyMessage); -}; - -// 跳转到常用语页面 -const goToCommonPhrases = () => { - uni.navigateTo({ - url: '/pages/message/common-phrases' - }); -}; - -// 跳转到宣教文章页面 -const goToArticleList = () => { - uni.navigateTo({ - url: `/pages/message/article-list?groupId=${props.groupId}&userId=${props.userId}&corpId=${props.corpId}` - }); -}; - -// 跳转到问卷列表页面 -const goToSurveyList = () => { - uni.navigateTo({ - url: '/pages/message/survey-list' - }); -}; - -// 结束问诊 -const handleEndConsult = () => { - uni.showModal({ - title: '确认结束问诊', - content: '确定要结束本次问诊吗?结束后将无法继续对话。', - confirmText: '确定结束', - cancelText: '取消', - success: (res) => { - if (res.confirm) { - // 关闭功能面板 - showMorePanel.value = false; - // 触发父组件的结束问诊事件 - emit('endConsult'); - } - } - }); -}; - const morePanelButtons = [ { text: "照片", icon: "/static/icon/zhaopian.png", action: showImagePicker }, - { - text: "回访任务", - icon: "/static/icon/zhaopian.png", - action: showImagePicker, - }, - { - text: "常用语", - icon: "/static/icon/changyongyu.png", - action: goToCommonPhrases, - }, - { - text: "宣教", - icon: "/static/icon/xuanjiaowenzhang.png", - action: goToArticleList, - }, - { - text: "问卷", - icon: "/static/icon/wenjuan.png", - action: goToSurveyList, - }, - { - text: "结束问诊", - icon: "/static/icon/jieshuzixun.png", - action: handleEndConsult, - }, ]; function handleInputFocus() { diff --git a/pages/message/components/consult-apply.vue b/pages/message/components/consult-apply.vue new file mode 100644 index 0000000..84c533d --- /dev/null +++ b/pages/message/components/consult-apply.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/pages/message/components/consult-cancel.vue b/pages/message/components/consult-cancel.vue index d3d334c..7187416 100644 --- a/pages/message/components/consult-cancel.vue +++ b/pages/message/components/consult-cancel.vue @@ -51,10 +51,10 @@ const handleCancel = () => { justify-content: center; } -.btn-cancel { +.btn-cancel, +.btn-reapply { width: 100%; - height: 80rpx; - border-radius: 8rpx; + heiger-radius: 8rpx; font-size: 28rpx; border: none; display: flex; diff --git a/pages/message/index.vue b/pages/message/index.vue index d6add75..ec8628d 100644 --- a/pages/message/index.vue +++ b/pages/message/index.vue @@ -114,9 +114,12 @@ + + + @@ -163,12 +165,12 @@ import MessageTypes from "./components/message-types.vue"; import ChatInput from "./components/chat-input.vue"; import SystemMessage from "./components/system-message.vue"; import ConsultCancel from "./components/consult-cancel.vue"; +import ConsultApply from "./components/consult-apply.vue"; const timChatManager = globalTimChatManager; -// 获取环境变量 -const env = __VITE_ENV__; -const corpId = env.MP_CORP_ID || ""; +// corpId 从群组信息中获取 +const corpId = ref(""); // 获取登录状态 const { account, openid, isIMInitialized } = storeToRefs(useAccountStore()); @@ -197,8 +199,17 @@ const chatInfo = ref({ // 评价弹窗状态 const isEvaluationPopupOpen = ref(false); -// 取消申请状态 -const showConsultCancel = ref(false); +// 订单状态 +const orderStatus = ref(""); + +// 计算弹框显示状态 +const showConsultCancel = computed(() => orderStatus.value === "pending"); +const showConsultApply = computed( + () => + orderStatus.value === "finished" || + orderStatus.value === "cancelled" || + orderStatus.value === "rejected" +); // 消息列表相关状态 const messageList = ref([]); @@ -215,77 +226,75 @@ function isSystemMessage(message) { if (message.type !== "TIMCustomElem") { return false; } - try { - // 检查 payload.data 是否包含系统消息标记 if (message.payload?.data) { const data = typeof message.payload.data === "string" ? JSON.parse(message.payload.data) : message.payload.data; - - // 检查是否为系统消息类型 if (data.type === "system_message") { return true; } } - - // 检查 description 是否为系统消息标记 if (message.payload?.description === "系统消息标记") { return true; } - - // 兼容旧的系统消息格式 if (message.payload?.description === "SYSTEM_NOTIFICATION") { return true; } } catch (error) { console.error("判断系统消息失败:", error); } - return false; } +// 获取群组订单状态 +const fetchGroupOrderStatus = async () => { + try { + const result = await api("getGroupListByGroupId", { + groupId: groupId.value, + }); + + if (result.success && result.data) { + orderStatus.value = result.data.orderStatus || ""; + corpId.value = result.data.corpId || ""; + console.log("获取群组订单状态:", { + orderStatus: orderStatus.value, + corpId: corpId.value, + }); + } else { + console.error("获取群组订单状态失败:", result.message); + } + } catch (error) { + console.error("获取群组订单状态异常:", error); + } +}; + +// 处理接收到的系统消息 +function handleSystemMessageReceived(message) { + try { + if (!message.payload?.data) return; + + const data = + typeof message.payload.data === "string" + ? JSON.parse(message.payload.data) + : message.payload.data; + + if (data.type !== "system_message") return; + + console.log("收到系统消息,类型:", data.messageType); + + // 系统消息触发时,重新获取订单状态 + fetchGroupOrderStatus(); + } catch (error) { + console.error("处理系统消息失败:", error); + } +} + // 检查是否有待接诊的系统消息 function checkConsultPendingStatus() { - // 查找最新的系统消息 - for (let i = messageList.value.length - 1; i >= 0; i--) { - const message = messageList.value[i]; - - if (message.type === "TIMCustomElem" && message.payload?.data) { - try { - const data = - typeof message.payload.data === "string" - ? JSON.parse(message.payload.data) - : message.payload.data; - - // 如果是 consult_pending 类型的系统消息,显示取消申请组件 - if ( - data.type === "system_message" && - data.messageType === "consult_pending" - ) { - showConsultCancel.value = true; - return; - } - - // 如果是其他系统消息类型(如已接诊、已结束、已拒绝等),隐藏取消申请组件 - if ( - data.type === "system_message" && - (data.messageType === "consult_accepted" || - data.messageType === "consult_ended" || - data.messageType === "consult_rejected") - ) { - showConsultCancel.value = false; - return; - } - } catch (error) { - console.error("解析系统消息失败:", error); - } - } - } - - // 如果没有找到相关系统消息,隐藏取消申请组件 - showConsultCancel.value = false; + // 直接获取最新的订单状态 + fetchGroupOrderStatus(); } // 获取消息气泡样式类 @@ -324,7 +333,7 @@ const checkLoginAndInitTIM = async () => { uni.showLoading({ title: "连接中...", }); - const success = await initIMAfterLogin(openid.value); + const success = await initIMAfterLogin(); uni.hideLoading(); if (!success) { uni.showToast({ @@ -379,6 +388,11 @@ const initTIMCallbacks = async () => { messageList.value.push(message); console.log("✓ 添加消息到列表,当前消息数量:", messageList.value.length); + // 检查是否为系统消息,并处理状态更新 + if (isSystemMessage(message)) { + handleSystemMessageReceived(message); + } + // 检查是否有待接诊的系统消息 checkConsultPendingStatus(); @@ -502,7 +516,7 @@ const initTIMCallbacks = async () => { }; // 加载消息列表 -const loadMessageList = () => { +const loadMessageList = async () => { if (isLoading.value) { console.log("正在加载中,跳过重复加载"); return; @@ -519,6 +533,9 @@ const loadMessageList = () => { mask: false, }); + // 获取群组订单状态 + await fetchGroupOrderStatus(); + timChatManager.enterConversation(chatInfo.value.conversationID || "test1"); // 标记会话为已读 @@ -691,16 +708,6 @@ onHide(() => { stopIMMonitoring(); }); -const sendCommonPhrase = (content) => { - if (chatInputRef.value) { - chatInputRef.value.sendTextMessageFromPhrase(content); - } -}; -// 暴露方法给常用语页面调用 -defineExpose({ - sendCommonPhrase, -}); - // 处理取消申请 const handleCancelConsult = async () => { try { @@ -716,14 +723,22 @@ const handleCancelConsult = async () => { // 调用取消咨询申请接口 const result = await api("cancelConsultApplication", { groupId: groupId.value, - corpId: corpId, + corpId: corpId.value, }); uni.hideLoading(); if (result.success) { - showConsultCancel.value = false; - uni.switchTab({ - url: "/pages/home/home", + // 重新获取订单状态 + await fetchGroupOrderStatus(); + uni.showToast({ + title: "已取消申请", + icon: "success", }); + // 延迟返回首页 + setTimeout(() => { + uni.switchTab({ + url: "/pages/home/home", + }); + }, 1500); } else { throw new Error(result.message || "取消申请失败"); } @@ -747,34 +762,84 @@ const handleCancelConsult = async () => { } }; -// 处理结束问诊 -const handleEndConsult = async () => { +// 处理咨询申请 +const handleApplyConsult = async () => { try { - uni.showLoading({ - title: "处理中...", - }); - // 调用结束问诊接口,直接传入 groupId - const result = await api("endConsultation", { - groupId: groupId.value, - adminAccount: account.value?.userId || "", - extraData: { - endBy: account.value?.userId || "", - endByName: account.value?.name || "医生", - endReason: "问诊完成", + uni.showModal({ + title: "提示", + content: "确定要重新申请咨询吗?", + success: async (res) => { + if (res.confirm) { + uni.showLoading({ + title: "申请中...", + }); + try { + // 获取当前群组信息,提取客户ID和corpId + const groupInfo = await api("getGroupListByGroupId", { + groupId: groupId.value, + }); + + if (!groupInfo.success || !groupInfo.data) { + throw new Error("获取群组信息失败"); + } + + const customerId = groupInfo.data.customerId; + const groupCorpId = groupInfo.data.corpId; + + if (!customerId) { + throw new Error("无法获取客户信息"); + } + + // 调用创建咨询群组接口(重新申请) + const result = await api("createConsultGroup", { + teamId: groupInfo.data.teamId || "", + corpId: groupCorpId || corpId.value, + customerId: customerId, + customerImUserId: openid.value, + }); + + uni.hideLoading(); + + if (result.success) { + const { groupId: newGroupId, isExisting } = result.data; + + // 重新获取订单状态 + await fetchGroupOrderStatus(); + + uni.showToast({ + title: isExisting ? "已重新发起申请" : "申请已发送", + icon: "success", + }); + + // 如果是新群组,跳转到新的聊天页面 + if (!isExisting && newGroupId !== groupId.value) { + setTimeout(() => { + uni.redirectTo({ + url: `/pages/message/index?conversationID=GROUP${newGroupId}&groupID=${newGroupId}`, + }); + }, 1500); + } else { + // 刷新当前页面消息 + setTimeout(() => { + loadMessageList(); + }, 1000); + } + } else { + throw new Error(result.message || "申请失败"); + } + } catch (error) { + console.error("申请失败:", error); + uni.hideLoading(); + uni.showToast({ + title: error.message || "操作失败", + icon: "none", + }); + } + } }, }); - uni.hideLoading(); - if (result.success) { - uni.showToast({ - title: "问诊已结束", - icon: "success", - }); - } else { - throw new Error(result.message || "操作失败"); - } } catch (error) { - console.error("结束问诊失败:", error); - uni.hideLoading(); + console.error("申请失败:", error); uni.showToast({ title: error.message || "操作失败", icon: "none", @@ -791,100 +856,6 @@ onUnmounted(() => { timChatManager.setCallback("onMessageReceived", null); timChatManager.setCallback("onMessageListLoaded", null); timChatManager.setCallback("onError", null); - // 移除问卷发送监听 - uni.$off("sendSurvey"); -}); - -// 监听问卷发送事件 -uni.$on("sendSurvey", async (data) => { - const { survey, corpId, userId, sendSurveyId } = data; - - if (!survey || !survey._id) { - uni.showToast({ - title: "问卷信息不完整", - icon: "none", - }); - return; - } - try { - // 获取环境变量 - const env = __VITE_ENV__; - const baseUrl = env.VITE_PATIENT_PAGE_BASE_URL || ""; - const surveyUrl = env.VITE_SURVEY_URL || ""; - - // 获取客户信息 - const customerId = chatInfo.value.userID || ""; - const customerName = chatInfo.value.customerName || ""; - - // 创建问卷记录 - const { createSurveyRecord } = await import("@/utils/api.js"); - const recordRes = await createSurveyRecord({ - corpId, - userId, - surveryId: survey._id, - memberId: customerId, - customer: customerName, - sendSurveyId, - }); - - if (!recordRes.success) { - throw new Error(recordRes.message || "创建问卷记录失败"); - } - - const answerId = recordRes.data?.id || ""; - - // 构建问卷链接 - let surveyLink = ""; - if (survey.createBy === "system") { - // 系统问卷 - surveyLink = `${surveyUrl}?corpId=${corpId}&surveyId=${survey.surveyId}&memberId=${customerId}&sendSurveyId=${sendSurveyId}&userId=${userId}`; - } else { - // 自定义问卷 - surveyLink = `${baseUrl}pages/survery/fill?corpId=${corpId}&surveryId=${ - survey._id - }&memberId=${customerId}&answerId=${answerId}&name=${encodeURIComponent( - customerName - )}`; - } - - // 创建自定义消息 - const customMessage = { - data: JSON.stringify({ - type: "survey", - title: survey.name || "填写问卷", - desc: "请填写问卷", - url: surveyLink, - imgUrl: - "https://796f-youcan-clouddev-1-8ewcqf31dbb2b5-1317294507.tcb.qcloud.la/other/19-%E9%97%AE%E5%8D%B7.png?sign=55a4cd77c418b2c548b65792a2cf6bce&t=1701328694", - }), - description: "SURVEY", - extension: "", - }; - - // 发送自定义消息 - const message = timChatManager.tim.createCustomMessage({ - to: chatInfo.value.conversationID.replace("GROUP", ""), - conversationType: timChatManager.TIM.TYPES.CONV_GROUP, - payload: customMessage, - }); - - const sendResult = await timChatManager.tim.sendMessage(message); - - if (sendResult.code === 0) { - uni.showToast({ - title: "发送成功", - icon: "success", - }); - } else { - throw new Error(sendResult.message || "发送失败"); - } - } catch (error) { - console.error("发送问卷失败:", error); - uni.showToast({ - title: error.message || "发送失败", - icon: "none", - }); - } }); diff --git a/pages/message/message.vue b/pages/message/message.vue index a9a9e3c..c58b9c4 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -95,7 +95,7 @@ const initIM = async () => { uni.showLoading({ title: "连接中...", }); - const success = await initIMAfterLogin(openid.value); + const success = await initIMAfterLogin(); uni.hideLoading(); if (!success) { diff --git a/pages/message/survey-list.vue b/pages/message/survey-list.vue deleted file mode 100644 index 53a5261..0000000 --- a/pages/message/survey-list.vue +++ /dev/null @@ -1,446 +0,0 @@ - - - - - diff --git a/store/account.js b/store/account.js index 5b5e04f..b58b09a 100644 --- a/store/account.js +++ b/store/account.js @@ -43,12 +43,12 @@ export default defineStore("accountStore", () => { loading.value = false } - async function initIMAfterLogin(userID) { + async function initIMAfterLogin() { if (isIMInitialized.value) { return true; } try { - await initGlobalTIM(userID); + await initGlobalTIM(); isIMInitialized.value = true; return true; } catch (error) {