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 @@
-
-
-
-
- 加载中...
-
-
-
- {{ error }}
-
-
-
-
-
- {{ articleData.title }}
- {{ articleData.date }}
-
-
-
-
-
-
-
-
-
-
-
-
-
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 @@
-
-
-
-
-
-
-
-
-
-
-
- 加载中...
-
-
-
-
-
-
-
-
-
- {{ article.title }}
-
- {{ article.date }}
-
-
-
-
-
-
-
- 加载中...
-
-
-
- 没有更多了
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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 @@
-
-
-
-
-
-
-
-
-
-
- {{ phrase.content }}
-
-
- 编辑
-
-
- 删除
-
-
-
-
-
- 暂无常用语
- 点击下方按钮添加常用语
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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 @@
+
+
+
scrollToBottom(true)"
@messageSent="() => scrollToBottom(true)"
- @endConsult="handleEndConsult"
/>
@@ -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 @@
-
-
-
-
-
-
-
-
-
-
-
- 加载中...
-
-
-
-
-
-
-
-
-
- {{ survey.name }}
- {{
- survey.description || "暂无问卷说明"
- }}
-
-
-
-
-
-
-
-
- 加载中...
-
-
-
- 没有更多了
-
-
-
-
-
-
-
-
-
-
-
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) {