no message
This commit is contained in:
parent
b9385ebf02
commit
26bd604e45
@ -64,7 +64,7 @@
|
|||||||
<view class="content">{{ i.taskContent || "暂无内容" }}</view>
|
<view class="content">{{ i.taskContent || "暂无内容" }}</view>
|
||||||
<view v-if="i.sendContent || (i.fileList && i.fileList.length > 0)" class="send-content-wrapper">
|
<view v-if="i.sendContent || (i.fileList && i.fileList.length > 0)" class="send-content-wrapper">
|
||||||
<view class="send-content-section">
|
<view class="send-content-section">
|
||||||
<view class="send-content-label">【发送内容】</view>
|
<view class="send-content-label">发送内容:</view>
|
||||||
<view class="send-content-body">
|
<view class="send-content-body">
|
||||||
<view v-if="i.sendContent" class="send-text">{{ i.sendContent }}</view>
|
<view v-if="i.sendContent" class="send-text">{{ i.sendContent }}</view>
|
||||||
<view v-if="i.fileList && i.fileList.length > 0" class="file-list">
|
<view v-if="i.fileList && i.fileList.length > 0" class="file-list">
|
||||||
@ -204,6 +204,7 @@ import dayjs from "dayjs";
|
|||||||
import api from "@/utils/api";
|
import api from "@/utils/api";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
import { toast } from "@/utils/widget";
|
import { toast } from "@/utils/widget";
|
||||||
|
import { handleFollowUpMessages } from "@/utils/send-message-helper";
|
||||||
import {
|
import {
|
||||||
getTodoEventTypeLabel,
|
getTodoEventTypeLabel,
|
||||||
getTodoEventTypeOptions,
|
getTodoEventTypeOptions,
|
||||||
@ -221,6 +222,15 @@ const accountStore = useAccountStore();
|
|||||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||||
const { getDoctorInfo } = accountStore;
|
const { getDoctorInfo } = accountStore;
|
||||||
|
|
||||||
|
function getUserId() {
|
||||||
|
return doctorInfo.value?.userid || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCorpId() {
|
||||||
|
const team = uni.getStorageSync("ykt_case_current_team") || {};
|
||||||
|
return team.corpId || doctorInfo.value?.corpId || "";
|
||||||
|
}
|
||||||
|
|
||||||
const statusTabs = [
|
const statusTabs = [
|
||||||
{ label: "全部", value: "all" },
|
{ label: "全部", value: "all" },
|
||||||
{ label: "待处理", value: "processing" },
|
{ label: "待处理", value: "processing" },
|
||||||
@ -275,23 +285,6 @@ const typeSelectedMap = computed(() => {
|
|||||||
}, {});
|
}, {});
|
||||||
});
|
});
|
||||||
|
|
||||||
function getUserId() {
|
|
||||||
const d = doctorInfo.value || {};
|
|
||||||
const a = account.value || {};
|
|
||||||
return (
|
|
||||||
String(
|
|
||||||
d.userid || d.userId || d.corpUserId || a.userid || a.userId || ""
|
|
||||||
) || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCorpId() {
|
|
||||||
const t = uni.getStorageSync("ykt_case_current_team") || {};
|
|
||||||
const a = account.value || {};
|
|
||||||
const d = doctorInfo.value || {};
|
|
||||||
return String(t.corpId || a.corpId || d.corpId || "") || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ensureDoctor() {
|
async function ensureDoctor() {
|
||||||
if (doctorInfo.value) return;
|
if (doctorInfo.value) return;
|
||||||
if (!account.value?.openid) return;
|
if (!account.value?.openid) return;
|
||||||
@ -537,9 +530,12 @@ async function sendFollowUp(todo) {
|
|||||||
messages.push({
|
messages.push({
|
||||||
type: "article",
|
type: "article",
|
||||||
content: {
|
content: {
|
||||||
|
_id: file.file?._id || file._id,
|
||||||
title: file.file?.name || file.name || "宣教文章",
|
title: file.file?.name || file.name || "宣教文章",
|
||||||
url: file.file?.url || file.URL,
|
url: file.file?.url || file.URL,
|
||||||
desc: file.file?.subtitle || "",
|
subtitle: file.file?.subtitle || "",
|
||||||
|
cover: file.file?.cover || "",
|
||||||
|
articleId: file.file?._id || file._id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (file.type === "questionnaire" && file.file?.surveryId) {
|
} else if (file.type === "questionnaire" && file.file?.surveryId) {
|
||||||
@ -547,7 +543,8 @@ async function sendFollowUp(todo) {
|
|||||||
messages.push({
|
messages.push({
|
||||||
type: "questionnaire",
|
type: "questionnaire",
|
||||||
content: {
|
content: {
|
||||||
title: file.file?.name || file.name || "问卷",
|
_id: file.file?._id || file._id,
|
||||||
|
name: file.file?.name || file.name || "问卷",
|
||||||
surveryId: file.file?.surveryId || file.surveryId,
|
surveryId: file.file?.surveryId || file.surveryId,
|
||||||
url: file.file?.url || file.URL,
|
url: file.file?.url || file.URL,
|
||||||
},
|
},
|
||||||
@ -556,15 +553,19 @@ async function sendFollowUp(todo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发事件,通知父组件发送消息
|
// 调用统一的消息发送处理函数
|
||||||
uni.$emit("send-followup-message", {
|
const success = await handleFollowUpMessages(messages, {
|
||||||
messages,
|
userId: getUserId(),
|
||||||
followupId: todo._id,
|
customerId: props.archiveId,
|
||||||
followupData: todo,
|
customerName: props.data?.name || "",
|
||||||
|
corpId: getCorpId(),
|
||||||
|
env: __VITE_ENV__,
|
||||||
});
|
});
|
||||||
|
|
||||||
toast("消息已发送");
|
if (success) {
|
||||||
uni.navigateBack();
|
toast("消息已发送");
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- filter popup ----
|
// ---- filter popup ----
|
||||||
@ -863,6 +864,7 @@ watch(
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
width: 330rpx;
|
||||||
}
|
}
|
||||||
.file-type-image .file-name {
|
.file-type-image .file-name {
|
||||||
color: #0877f1;
|
color: #0877f1;
|
||||||
|
|||||||
@ -111,6 +111,7 @@ import { ref, onMounted } from "vue";
|
|||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
|
import { sendArticleMessage } from "@/utils/send-message-helper.js";
|
||||||
import EmptyData from "@/components/empty-data.vue";
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
|
|
||||||
const accountStore = useAccountStore();
|
const accountStore = useAccountStore();
|
||||||
@ -316,69 +317,25 @@ const sendArticle = async (article) => {
|
|||||||
try {
|
try {
|
||||||
const { doctorInfo } = useAccountStore();
|
const { doctorInfo } = useAccountStore();
|
||||||
|
|
||||||
// 1. 调用后端API记录发送
|
// 使用统一的消息发送助手
|
||||||
const result = await api("sendArticleMessage", {
|
const success = await sendArticleMessage(
|
||||||
groupId: pageParams.value.groupId,
|
{
|
||||||
fromAccount: doctorInfo.userid,
|
_id: article._id,
|
||||||
articleId: article._id,
|
title: article.title || "宣教文章",
|
||||||
title: article.title || "宣教文章",
|
cover: article.cover || "",
|
||||||
imgUrl: article.cover || "",
|
url: article.url || "",
|
||||||
desc: "点击查看详情",
|
subtitle: article.subtitle || "",
|
||||||
});
|
},
|
||||||
|
{
|
||||||
if (result.success) {
|
articleId: article._id,
|
||||||
// 2. 通过IM系统发送自定义消息到聊天列表
|
userId: doctorInfo?.userid,
|
||||||
try {
|
customerId: pageParams.value.patientId,
|
||||||
// 获取全局IM管理器
|
corpId: corpId,
|
||||||
const { globalTimChatManager } = await import("@/utils/tim-chat.js");
|
|
||||||
|
|
||||||
if (globalTimChatManager && globalTimChatManager.tim && globalTimChatManager.isLoggedIn) {
|
|
||||||
// 重要:设置当前会话ID,确保消息发送到正确的群聊
|
|
||||||
const conversationID = `GROUP${pageParams.value.groupId}`;
|
|
||||||
globalTimChatManager.currentConversationID = conversationID;
|
|
||||||
|
|
||||||
console.log("设置当前会话ID:", conversationID);
|
|
||||||
|
|
||||||
// 构建自定义消息数据
|
|
||||||
const customMessageData = {
|
|
||||||
messageType: "article",
|
|
||||||
title: article.title || "宣教文章",
|
|
||||||
articleId: article._id,
|
|
||||||
cover: article.cover || "",
|
|
||||||
desc: "点击查看详情",
|
|
||||||
content: article.title || "宣教文章"
|
|
||||||
};
|
|
||||||
|
|
||||||
// 发送自定义消息
|
|
||||||
const sendResult = await globalTimChatManager.sendCustomMessage(customMessageData);
|
|
||||||
if (sendResult && sendResult.success) {
|
|
||||||
console.log("✓ 文章消息已通过IM系统发送");
|
|
||||||
} else {
|
|
||||||
console.warn("⚠️ 文章消息发送失败:", sendResult?.error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn("⚠️ IM系统未就绪,消息可能不会显示在聊天列表");
|
|
||||||
}
|
|
||||||
} catch (imError) {
|
|
||||||
console.error("通过IM系统发送消息失败:", imError);
|
|
||||||
// IM发送失败不影响后端记录,继续返回
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 记录文章发送记录
|
|
||||||
try {
|
|
||||||
await api("addArticleSendRecord", {
|
|
||||||
articleId: article._id,
|
|
||||||
userId: doctorInfo.userid,
|
|
||||||
customerId: pageParams.value.patientId,
|
|
||||||
corpId: corpId,
|
|
||||||
});
|
|
||||||
} catch (recordError) {
|
|
||||||
console.error("记录文章发送失败:", recordError);
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
} else {
|
|
||||||
throw new Error(result.message || "发送失败");
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("发送文章失败:", error);
|
console.error("发送文章失败:", error);
|
||||||
|
|||||||
@ -81,7 +81,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits(["messageSent", "scrollToBottom", "endConsult"]);
|
const emit = defineEmits(["messageSent", "scrollToBottom", "endConsult", "openConsult"]);
|
||||||
|
|
||||||
// 输入相关状态
|
// 输入相关状态
|
||||||
const inputText = ref("");
|
const inputText = ref("");
|
||||||
@ -404,6 +404,24 @@ const handleEndConsult = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 开启会话
|
||||||
|
const handleOpenConsult = () => {
|
||||||
|
uni.showModal({
|
||||||
|
title: "确认开启会话",
|
||||||
|
content: "确定要重新开启本次会话吗?",
|
||||||
|
confirmText: "确定开启",
|
||||||
|
cancelText: "取消",
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 关闭功能面板
|
||||||
|
showMorePanel.value = false;
|
||||||
|
// 触发父组件的开启会话事件
|
||||||
|
emit("openConsult");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const morePanelButtons = [
|
const morePanelButtons = [
|
||||||
{ text: "照片", icon: "/static/icon/zhaopian.png", action: showImagePicker },
|
{ text: "照片", icon: "/static/icon/zhaopian.png", action: showImagePicker },
|
||||||
{
|
{
|
||||||
@ -431,6 +449,11 @@ const morePanelButtons = [
|
|||||||
icon: "/static/icon/jieshuzixun.png",
|
icon: "/static/icon/jieshuzixun.png",
|
||||||
action: handleEndConsult,
|
action: handleEndConsult,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: "开启会话",
|
||||||
|
icon: "/static/icon/kaiqihuihua.png",
|
||||||
|
action: handleOpenConsult,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function handleInputFocus() {
|
function handleInputFocus() {
|
||||||
|
|||||||
@ -166,6 +166,7 @@
|
|||||||
@scrollToBottom="() => scrollToBottom(true)"
|
@scrollToBottom="() => scrollToBottom(true)"
|
||||||
@messageSent="() => scrollToBottom(true)"
|
@messageSent="() => scrollToBottom(true)"
|
||||||
@endConsult="handleEndConsult"
|
@endConsult="handleEndConsult"
|
||||||
|
@openConsult="handleOpenConsult"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -962,6 +963,43 @@ const handleEndConsult = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理开启会话
|
||||||
|
const handleOpenConsult = async () => {
|
||||||
|
try {
|
||||||
|
uni.showLoading({
|
||||||
|
title: "处理中...",
|
||||||
|
});
|
||||||
|
// 调用开启会话接口
|
||||||
|
const result = await api("openConsultation", {
|
||||||
|
groupId: groupId.value,
|
||||||
|
adminAccount: account.value?.userId || "",
|
||||||
|
extraData: {
|
||||||
|
openedBy: account.value?.userId || "",
|
||||||
|
openedByName: account.value?.name || "医生",
|
||||||
|
openReason: "重新开启会话",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
uni.hideLoading();
|
||||||
|
if (result.success) {
|
||||||
|
// 重新获取订单状态
|
||||||
|
await fetchGroupOrderStatus();
|
||||||
|
uni.showToast({
|
||||||
|
title: "会话已开启",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error(result.message || "操作失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("开启会话失败:", error);
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.showToast({
|
||||||
|
title: error.message || "操作失败",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 页面卸载
|
// 页面卸载
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearMessageCache();
|
clearMessageCache();
|
||||||
|
|||||||
@ -90,6 +90,7 @@ import { ref, onMounted } from "vue";
|
|||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
import { globalTimChatManager } from "@/utils/tim-chat.js";
|
import { globalTimChatManager } from "@/utils/tim-chat.js";
|
||||||
|
import { sendSurveyMessage } from "@/utils/send-message-helper.js";
|
||||||
import EmptyData from "@/components/empty-data.vue";
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
@ -315,48 +316,23 @@ const sendSurvey = async (survey) => {
|
|||||||
const doctorInfo = accountStore.doctorInfo;
|
const doctorInfo = accountStore.doctorInfo;
|
||||||
userId.value = doctorInfo?.userid;
|
userId.value = doctorInfo?.userid;
|
||||||
|
|
||||||
// 生成发送ID
|
// 使用统一的消息发送助手
|
||||||
const sendSurveyId = generateRandomString(10);
|
const success = await sendSurveyMessage(
|
||||||
|
{
|
||||||
// 创建问卷记录
|
_id: survey._id,
|
||||||
const createRecordRes = await api("createSurveyRecord", {
|
name: survey.name || "问卷",
|
||||||
corpId: corpId,
|
surveryId: survey.surveryId || survey._id,
|
||||||
userId: userId.value,
|
url: survey.url || "",
|
||||||
surveryId: survey._id,
|
},
|
||||||
memberId: customerId.value,
|
{
|
||||||
customer: customerName.value,
|
userId: userId.value,
|
||||||
sendSurveyId: sendSurveyId,
|
customerId: customerId.value,
|
||||||
});
|
customerName: customerName.value,
|
||||||
|
corpId: corpId,
|
||||||
if (!createRecordRes.success) {
|
}
|
||||||
uni.showToast({
|
|
||||||
title: createRecordRes.message || "创建问卷记录失败",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
loading.value = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const answerId = createRecordRes?.id || "";
|
|
||||||
|
|
||||||
// 生成发送链接
|
|
||||||
const sendLink = generateSendLink(
|
|
||||||
survey,
|
|
||||||
answerId,
|
|
||||||
customerId.value,
|
|
||||||
customerName.value,
|
|
||||||
sendSurveyId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 构建自定义消息
|
if (success) {
|
||||||
const customMessage = buildSurveyMessage(survey, sendLink);
|
|
||||||
|
|
||||||
// 发送自定义消息到IM
|
|
||||||
const result = await timChatManager.sendCustomMessage(
|
|
||||||
customMessage,
|
|
||||||
"SURVEY"
|
|
||||||
);
|
|
||||||
if (result.success) {
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: "发送成功",
|
title: "发送成功",
|
||||||
icon: "success",
|
icon: "success",
|
||||||
@ -365,8 +341,6 @@ const sendSurvey = async (survey) => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
}, 500);
|
}, 500);
|
||||||
} else {
|
|
||||||
throw new Error(result.error || "发送失败");
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("发送问卷失败:", error);
|
console.error("发送问卷失败:", error);
|
||||||
|
|||||||
330
utils/send-message-helper.js
Normal file
330
utils/send-message-helper.js
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/**
|
||||||
|
* 消息发送助手 - 统一处理不同类型消息的发送
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { globalTimChatManager } from './tim-chat.js';
|
||||||
|
import api from './api.js';
|
||||||
|
import { toast } from './widget.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送文字消息
|
||||||
|
* @param {string} content - 文字内容
|
||||||
|
* @returns {Promise<boolean>} 发送是否成功
|
||||||
|
*/
|
||||||
|
export async function sendTextMessage(content) {
|
||||||
|
if (!content || !content.trim()) {
|
||||||
|
toast('文字内容不能为空');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager?.isLoggedIn) {
|
||||||
|
toast('IM系统未就绪,请稍后重试');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接调用 tim-chat 的 sendTextMessage 方法
|
||||||
|
const result = await globalTimChatManager.sendTextMessage(content.trim());
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
toast(result?.error || '发送文字消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送文字消息异常:', error);
|
||||||
|
toast('发送文字消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送图片消息
|
||||||
|
* @param {string} imageUrl - 图片URL(字符串)
|
||||||
|
* @param {string} imageName - 图片名称(可选)
|
||||||
|
* @returns {Promise<boolean>} 发送是否成功
|
||||||
|
*/
|
||||||
|
export async function sendImageMessage(imageUrl, imageName = '图片') {
|
||||||
|
if (!imageUrl) {
|
||||||
|
toast('图片URL不能为空');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager?.isLoggedIn) {
|
||||||
|
toast('IM系统未就绪,请稍后重试');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接调用 tim-chat 的 sendImageMessage 方法
|
||||||
|
// tim-chat.js 中的 getImageUrl 方法可以处理 URL 字符串
|
||||||
|
const result = await globalTimChatManager.sendImageMessage(imageUrl);
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
toast(result?.error || '发送图片消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送图片消息异常:', error);
|
||||||
|
toast('发送图片消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送宣教文章消息
|
||||||
|
* @param {Object} article - 文章对象 { _id, title, cover, url }
|
||||||
|
* @param {Object} options - 额外选项 { groupId, patientId, corpId }
|
||||||
|
* @returns {Promise<boolean>} 发送是否成功
|
||||||
|
*/
|
||||||
|
export async function sendArticleMessage(article, options = {}) {
|
||||||
|
if (!article || !article._id) {
|
||||||
|
toast('文章信息不完整');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager?.isLoggedIn) {
|
||||||
|
toast('IM系统未就绪,请稍后重试');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建自定义消息 - 直接传递对象,sendCustomMessage会处理JSON序列化
|
||||||
|
const customMessageData = {
|
||||||
|
type: 'article',
|
||||||
|
title: article.title || '宣教文章',
|
||||||
|
articleId: article._id,
|
||||||
|
cover: article.cover || '',
|
||||||
|
desc: article.subtitle || '点击查看详情',
|
||||||
|
url: article.url || '',
|
||||||
|
messageType: 'article',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发送自定义消息
|
||||||
|
const result = await globalTimChatManager.sendCustomMessage(customMessageData);
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
// 记录文章发送记录(异步,不阻塞)
|
||||||
|
if (options.articleId && options.userId && options.customerId && options.corpId) {
|
||||||
|
api('addArticleSendRecord', {
|
||||||
|
articleId: options.articleId,
|
||||||
|
userId: options.userId,
|
||||||
|
customerId: options.customerId,
|
||||||
|
corpId: options.corpId,
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('记录文章发送失败:', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
toast(result?.error || '发送文章消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送文章消息异常:', error);
|
||||||
|
toast('发送文章消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送问卷消息
|
||||||
|
* @param {Object} survey - 问卷对象 { _id, name, surveryId, url, createBy }
|
||||||
|
* @param {Object} options - 额外选项 { userId, customerId, customerName, corpId, env }
|
||||||
|
* @returns {Promise<boolean>} 发送是否成功
|
||||||
|
*/
|
||||||
|
export async function sendSurveyMessage(survey, options = {}) {
|
||||||
|
if (!survey || !survey._id) {
|
||||||
|
toast('问卷信息不完整');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager?.isLoggedIn) {
|
||||||
|
toast('IM系统未就绪,请稍后重试');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成发送ID
|
||||||
|
const sendSurveyId = generateRandomString(10);
|
||||||
|
|
||||||
|
// 创建问卷记录
|
||||||
|
const createRecordRes = await api('createSurveyRecord', {
|
||||||
|
corpId: options.corpId,
|
||||||
|
userId: options.userId,
|
||||||
|
surveryId: survey._id,
|
||||||
|
memberId: options.customerId,
|
||||||
|
customer: options.customerName,
|
||||||
|
sendSurveyId: sendSurveyId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createRecordRes?.success) {
|
||||||
|
toast(createRecordRes?.message || '创建问卷记录失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const answerId = createRecordRes?.id || '';
|
||||||
|
|
||||||
|
// 生成问卷链接
|
||||||
|
const surveyLink = generateSendLink(
|
||||||
|
survey,
|
||||||
|
answerId,
|
||||||
|
options.customerId,
|
||||||
|
options.customerName,
|
||||||
|
sendSurveyId,
|
||||||
|
{
|
||||||
|
corpId: options.corpId,
|
||||||
|
userId: options.userId,
|
||||||
|
env: options.env,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 构建自定义消息
|
||||||
|
const customMessageData = buildSurveyMessage(survey, surveyLink);
|
||||||
|
|
||||||
|
// 发送自定义消息 - 直接传递消息对象,不再进行额外序列化
|
||||||
|
const result = await globalTimChatManager.sendCustomMessage(customMessageData);
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
toast(result?.error || '发送问卷消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送问卷消息异常:', error);
|
||||||
|
toast('发送问卷消息失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机字符串
|
||||||
|
* @param {number} length - 字符串长度
|
||||||
|
* @returns {string} 随机字符串
|
||||||
|
*/
|
||||||
|
function generateRandomString(length) {
|
||||||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成问卷发送链接
|
||||||
|
* @param {Object} survey - 问卷对象
|
||||||
|
* @param {string} answerId - 答卷ID
|
||||||
|
* @param {string} customerId - 客户ID
|
||||||
|
* @param {string} customerName - 客户名称
|
||||||
|
* @param {string} sendSurveyId - 发送问卷ID
|
||||||
|
* @param {Object} context - 上下文信息 { corpId, userId, env }
|
||||||
|
* @returns {string} 问卷链接
|
||||||
|
*/
|
||||||
|
function generateSendLink(survey, answerId, customerId, customerName, sendSurveyId, context = {}) {
|
||||||
|
const { corpId, userId, env } = context;
|
||||||
|
const isSystem = survey.createBy === 'system';
|
||||||
|
let url = '';
|
||||||
|
|
||||||
|
if (isSystem) {
|
||||||
|
// 系统问卷:使用 VITE_SURVEY_URL
|
||||||
|
url = `${env?.MP_SURVEY_URL}?corpId=${corpId}&surveryId=${survey.surveryId}&memberId=${customerId}&sendSurveyId=${sendSurveyId}&userId=${userId}`;
|
||||||
|
} else {
|
||||||
|
// 自定义问卷:使用 VITE_PATIENT_PAGE_BASE_URL
|
||||||
|
url = `${env?.MP_PATIENT_PAGE_BASE_URL}pages/survery/fill?corpId=${corpId}&surveryId=${survey._id}&memberId=${customerId}&unionid=unionid&answerId=${answerId}&name=${customerName || ''}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已有链接,直接使用并拼接额外参数
|
||||||
|
if (survey.url && survey.url.trim()) {
|
||||||
|
const separator = survey.url.includes('?') ? '&' : '?';
|
||||||
|
const params = [];
|
||||||
|
if (answerId) params.push(`answerId=${answerId}`);
|
||||||
|
if (sendSurveyId) params.push(`sendSurveyId=${sendSurveyId}`);
|
||||||
|
if (userId) params.push(`userId=${userId}`);
|
||||||
|
if (customerId) params.push(`memberId=${customerId}`);
|
||||||
|
|
||||||
|
if (params.length > 0) {
|
||||||
|
url = `${survey.url}${separator}${params.join('&')}`;
|
||||||
|
} else {
|
||||||
|
url = survey.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建问卷自定义消息
|
||||||
|
* @param {Object} survey - 问卷对象
|
||||||
|
* @param {string} surveyLink - 问卷链接
|
||||||
|
* @returns {Object} 自定义消息对象
|
||||||
|
*/
|
||||||
|
function buildSurveyMessage(survey, surveyLink) {
|
||||||
|
return {
|
||||||
|
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',
|
||||||
|
messageType: 'survey',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理回访任务消息发送
|
||||||
|
* @param {Object} messages - 消息数组
|
||||||
|
* @param {Object} context - 上下文信息 { userId, customerId, customerName, corpId }
|
||||||
|
* @returns {Promise<boolean>} 是否全部发送成功
|
||||||
|
*/
|
||||||
|
export async function handleFollowUpMessages(messages, context = {}) {
|
||||||
|
if (!Array.isArray(messages) || messages.length === 0) {
|
||||||
|
toast('没有要发送的消息');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let allSuccess = true;
|
||||||
|
|
||||||
|
for (const msg of messages) {
|
||||||
|
let success = false;
|
||||||
|
|
||||||
|
if (msg.type === 'text') {
|
||||||
|
success = await sendTextMessage(msg.content);
|
||||||
|
} else if (msg.type === 'image') {
|
||||||
|
success = await sendImageMessage(msg.content, msg.name);
|
||||||
|
} else if (msg.type === 'article') {
|
||||||
|
success = await sendArticleMessage(msg.content, {
|
||||||
|
articleId: msg.content.articleId,
|
||||||
|
userId: context.userId,
|
||||||
|
customerId: context.customerId,
|
||||||
|
corpId: context.corpId,
|
||||||
|
});
|
||||||
|
} else if (msg.type === 'questionnaire') {
|
||||||
|
success = await sendSurveyMessage(msg.content, {
|
||||||
|
userId: context.userId,
|
||||||
|
customerId: context.customerId,
|
||||||
|
customerName: context.customerName,
|
||||||
|
corpId: context.corpId,
|
||||||
|
env: context.env,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
allSuccess = false;
|
||||||
|
// 继续发送其他消息,不中断
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allSuccess;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('处理回访任务消息异常:', error);
|
||||||
|
toast('消息发送过程中出现错误');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user