diff --git a/.env.ip b/.env.ip index 93481d6..22cd3e5 100644 --- a/.env.ip +++ b/.env.ip @@ -1,7 +1,7 @@ MP_API_BASE_URL=http://192.168.60.2:8080 MP_IMAGE_URL=https://patient.youcan365.com MP_CACHE_PREFIX=development -MP_WX_APP_ID=wx93af55767423938e +MP_WX_APP_ID=wx1d8337a40c11d66c MP_CORP_ID=wwe3fb2faa52cf9dfb MP_TIM_SDK_APP_ID=1600123876 MP_INVITE_TEAMMATE_QRCODE=https://patient.youcan365.com/invite-teammate diff --git a/baseData/index.js b/baseData/index.js index 9d252b0..eb40923 100644 --- a/baseData/index.js +++ b/baseData/index.js @@ -37,3 +37,6 @@ export const statusClassNames = { cancelled: "text-gray", expired: "text-gray", } + + +export const titleList = ['主任医师', '副主任医师', '主治医师', '住院医师', '护士长', '主管护师', '护师', '护士', '技师', '其他'] \ No newline at end of file diff --git a/pages/case/components/archive-detail/follow-up-manage-tab.vue b/pages/case/components/archive-detail/follow-up-manage-tab.vue index e041c9d..9d1ba92 100644 --- a/pages/case/components/archive-detail/follow-up-manage-tab.vue +++ b/pages/case/components/archive-detail/follow-up-manage-tab.vue @@ -64,7 +64,7 @@ {{ i.taskContent || "暂无内容" }} - + {{ i.sendContent }} @@ -204,6 +204,7 @@ import dayjs from "dayjs"; import api from "@/utils/api"; import useAccountStore from "@/store/account"; import { toast } from "@/utils/widget"; +import { handleFollowUpMessages } from "@/utils/send-message-helper"; import { getTodoEventTypeLabel, getTodoEventTypeOptions, @@ -221,6 +222,15 @@ const accountStore = useAccountStore(); const { account, doctorInfo } = storeToRefs(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 = [ { label: "全部", value: "all" }, { 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() { if (doctorInfo.value) return; if (!account.value?.openid) return; @@ -537,9 +530,12 @@ async function sendFollowUp(todo) { messages.push({ type: "article", content: { + _id: file.file?._id || file._id, title: file.file?.name || file.name || "宣教文章", 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) { @@ -547,7 +543,8 @@ async function sendFollowUp(todo) { messages.push({ type: "questionnaire", 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, url: file.file?.url || file.URL, }, @@ -556,15 +553,19 @@ async function sendFollowUp(todo) { } } - // 触发事件,通知父组件发送消息 - uni.$emit("send-followup-message", { - messages, - followupId: todo._id, - followupData: todo, + // 调用统一的消息发送处理函数 + const success = await handleFollowUpMessages(messages, { + userId: getUserId(), + customerId: props.archiveId, + customerName: props.data?.name || "", + corpId: getCorpId(), + env: __VITE_ENV__, }); - toast("消息已发送"); - uni.navigateBack(); + if (success) { + toast("消息已发送"); + uni.navigateBack(); + } } // ---- filter popup ---- @@ -863,6 +864,7 @@ watch( text-overflow: ellipsis; white-space: nowrap; flex: 1; + width: 330rpx; } .file-type-image .file-name { color: #0877f1; diff --git a/pages/home/components/cert-popup.vue b/pages/home/components/cert-popup.vue index 59632b6..8deb31c 100644 --- a/pages/home/components/cert-popup.vue +++ b/pages/home/components/cert-popup.vue @@ -93,6 +93,9 @@ function confirm() { } function toService() { + uni.navigateTo({ + url: '/pages/work/service/contact-service' + }) close() } diff --git a/pages/login/login.vue b/pages/login/login.vue index 6cd4ed2..087be87 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -63,7 +63,7 @@ function remind() { function toHome() { uni.switchTab({ - url: "/pages/work/work", + url: "/pages/home/work-home", }); } diff --git a/pages/login/redirect-page.vue b/pages/login/redirect-page.vue index 37359bb..cbe9bd4 100644 --- a/pages/login/redirect-page.vue +++ b/pages/login/redirect-page.vue @@ -39,7 +39,7 @@ async function toJoinTeam(teamId) { if (res && res.success) { await toast('加入团队成功'); return uni.switchTab({ - url: '/pages/work/work' + url: '/pages/home/work-home' }) } else { await toast(res?.message || '加入团队失败') diff --git a/pages/message/article-list.vue b/pages/message/article-list.vue index ee835f9..b6a7334 100644 --- a/pages/message/article-list.vue +++ b/pages/message/article-list.vue @@ -111,6 +111,7 @@ import { ref, onMounted } from "vue"; import { onLoad } from "@dcloudio/uni-app"; import api from "@/utils/api.js"; import useAccountStore from "@/store/account.js"; +import { sendArticleMessage } from "@/utils/send-message-helper.js"; import EmptyData from "@/components/empty-data.vue"; const accountStore = useAccountStore(); @@ -349,71 +350,27 @@ const sendArticle = async (article) => { try { const { doctorInfo } = useAccountStore(); - // 1. 调用后端API记录发送 - const result = await api("sendArticleMessage", { - groupId: pageParams.value.groupId, - fromAccount: doctorInfo.userid, - articleId: article._id, - title: article.title || "宣教文章", - imgUrl: article.cover || "", - desc: "点击查看详情", - }); - - if (result.success) { - // 2. 通过IM系统发送自定义消息到聊天列表 - try { - // 获取全局IM管理器 - 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 ensureTeamId(); - await api("addArticleSendRecord", { - articleId: article._id, - userId: doctorInfo.userid, - customerId: pageParams.value.patientId, - corpId: corpId, - teamId: pageParams.value.teamId, - }); - } catch (recordError) { - console.error("记录文章发送失败:", recordError); + await ensureTeamId(); + // 使用统一的消息发送助手 + const success = await sendArticleMessage( + { + _id: article._id, + title: article.title || "宣教文章", + cover: article.cover || "", + url: article.url || "", + subtitle: article.subtitle || "", + }, + { + articleId: article._id, + userId: doctorInfo?.userid, + customerId: pageParams.value.patientId, + corpId: corpId, + teamId: pageParams.value.teamId, } + ); + if (success) { uni.navigateBack(); - } else { - throw new Error(result.message || "发送失败"); } } catch (error) { console.error("发送文章失败:", error); diff --git a/pages/message/chat.scss b/pages/message/chat.scss index 06cc9a9..749e586 100644 --- a/pages/message/chat.scss +++ b/pages/message/chat.scss @@ -10,7 +10,7 @@ $primary-color: #0877F1; top: 0; left: 0; right: 0; - bottom: 0; + bottom: 20rpx; display: flex; flex-direction: column; background-color: #f5f5f5; diff --git a/pages/message/common-phrases.vue b/pages/message/common-phrases.vue index 3f5bde1..3b664d0 100644 --- a/pages/message/common-phrases.vue +++ b/pages/message/common-phrases.vue @@ -627,10 +627,14 @@ $primary-gradient-start: #1b5cc8; $primary-gradient-end: #0877f1; .common-phrases-page { - height: 100vh; display: flex; flex-direction: column; background-color: #f5f5f5; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 20rpx; } // 自定义导航栏 diff --git a/pages/message/components/chat-input.vue b/pages/message/components/chat-input.vue index 3dc193d..0e0b18f 100644 --- a/pages/message/components/chat-input.vue +++ b/pages/message/components/chat-input.vue @@ -79,10 +79,11 @@ const props = defineProps({ teamId: { type: String, default: "" }, patientId: { type: String, default: "" }, corpId: { type: String, default: "" }, + orderStatus: { type: String, default: "" }, }); // Emits -const emit = defineEmits(["messageSent", "scrollToBottom", "endConsult"]); +const emit = defineEmits(["messageSent", "scrollToBottom", "endConsult", "openConsult"]); // 输入相关状态 const inputText = ref(""); @@ -405,34 +406,68 @@ const handleEndConsult = () => { }); }; -const morePanelButtons = [ - { text: "照片", icon: "/static/icon/zhaopian.png", action: showImagePicker }, - { - text: "回访任务", - icon: "/static/icon/huifangrenwu.png", - action: showFollowUpTasks, - }, - { - 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, - }, -]; +// 开启会话 +const handleOpenConsult = () => { + uni.showModal({ + title: "确认开启会话", + content: "确定要重新开启本次会话吗?", + confirmText: "确定开启", + cancelText: "取消", + success: (res) => { + if (res.confirm) { + // 关闭功能面板 + showMorePanel.value = false; + // 触发父组件的开启会话事件 + emit("openConsult"); + } + }, + }); +}; + +const morePanelButtons = computed(() => { + const buttons = [ + { text: "照片", icon: "/static/icon/zhaopian.png", action: showImagePicker }, + { + text: "回访任务", + icon: "/static/icon/huifangrenwu.png", + action: showFollowUpTasks, + }, + { + text: "常用语", + icon: "/static/icon/changyongyu.png", + action: goToCommonPhrases, + }, + { + text: "宣教", + icon: "/static/icon/xuanjiaowenzhang.png", + action: goToArticleList, + }, + { + text: "问卷", + icon: "/static/icon/wenjuan.png", + action: goToSurveyList, + }, + ]; + + // 根据订单状态显示不同的按钮 + if (props.orderStatus === "finished") { + // 已结束状态:显示"开启会话"按钮 + buttons.push({ + text: "开启会话", + icon: "/static/icon/kaiqihuihua.png", + action: handleOpenConsult, + }); + } else { + // 处理中状态:显示"结束问诊"按钮 + buttons.push({ + text: "结束问诊", + icon: "/static/icon/jieshuzixun.png", + action: handleEndConsult, + }); + } + + return buttons; +}); function handleInputFocus() { console.log("handleInputFocus"); diff --git a/pages/message/components/system-message.vue b/pages/message/components/system-message.vue index de4a907..df33d00 100644 --- a/pages/message/components/system-message.vue +++ b/pages/message/components/system-message.vue @@ -75,6 +75,8 @@ const text = computed(() => { return '问诊已结束'; case 'consult_timeout': return '问诊已超时'; + case 'consult_reopened': + return '会话已重新开启'; default: return systemMessageData.value.content || '[系统消息]'; } diff --git a/pages/message/index.vue b/pages/message/index.vue index 4692a2b..2dcb4b8 100644 --- a/pages/message/index.vue +++ b/pages/message/index.vue @@ -149,25 +149,27 @@ /> - + :userId="openid" + :teamId="teamId" + :patientId="patientId" + :corpId="corpId" + :patientInfo="patientInfo" + :orderStatus="orderStatus" + @scrollToBottom="() => scrollToBottom(true)" + @messageSent="() => scrollToBottom(true)" + @endConsult="handleEndConsult" + @openConsult="handleOpenConsult" + /> @@ -247,8 +249,8 @@ const patientInfo = ref({ }); // 患者ID -const patientId = ref(""); -const teamId = ref(""); +const patientId = ref(""); +const teamId = ref(""); // 计算弹框显示状态 - 只有 pending 状态才显示接受问诊组件 const showConsultAccept = computed(() => orderStatus.value === "pending"); @@ -301,20 +303,20 @@ function isSystemMessage(message) { } // 获取群组订单状态 -const fetchGroupOrderStatus = async () => { - try { - const result = await api("getGroupListByGroupId", { - groupId: groupId.value, - }); - - if (result.success && result.data) { - orderStatus.value = result.data.orderStatus || ""; - - // 更新导航栏标题为团队名称 - const teamName = result.data.team?.name || "群聊"; - updateNavigationTitle(teamName); - - teamId.value = result.data.teamId || result.data.team?.teamId || result.data.team?._id || ""; +const fetchGroupOrderStatus = async () => { + try { + const result = await api("getGroupListByGroupId", { + groupId: groupId.value, + }); + + if (result.success && result.data) { + orderStatus.value = result.data.orderStatus || ""; + + // 更新导航栏标题为团队名称 + const teamName = result.data.team?.name || "群聊"; + updateNavigationTitle(teamName); + + teamId.value = result.data.teamId || result.data.team?.teamId || result.data.team?._id || ""; // 更新患者信息 if (result.data.patient) { @@ -330,12 +332,12 @@ const fetchGroupOrderStatus = async () => { patientId.value = result.data.patientId.toString(); } - console.log("获取群组订单状态:", { - orderStatus: orderStatus.value, - teamName: teamName, - patientInfo: patientInfo.value, - groupId: groupId.value, - }); + console.log("获取群组订单状态:", { + orderStatus: orderStatus.value, + teamName: teamName, + patientInfo: patientInfo.value, + groupId: groupId.value, + }); } else { console.error("获取群组订单状态失败:", result.message); } @@ -966,6 +968,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(() => { clearMessageCache(); @@ -983,4 +1022,4 @@ onUnmounted(() => { + diff --git a/pages/message/survey-list.vue b/pages/message/survey-list.vue index 8c07d96..0507766 100644 --- a/pages/message/survey-list.vue +++ b/pages/message/survey-list.vue @@ -90,6 +90,7 @@ import { ref, onMounted } from "vue"; import api from "@/utils/api.js"; import useAccountStore from "@/store/account.js"; import { globalTimChatManager } from "@/utils/tim-chat.js"; +import { sendSurveyMessage } from "@/utils/send-message-helper.js"; import EmptyData from "@/components/empty-data.vue"; import { onLoad } from "@dcloudio/uni-app"; const env = __VITE_ENV__; @@ -354,51 +355,25 @@ const sendSurvey = async (survey) => { const doctorInfo = accountStore.doctorInfo; userId.value = doctorInfo?.userid; - // 生成发送ID - const sendSurveyId = generateRandomString(10); - await ensureTeamId(); - - // 创建问卷记录 - const createRecordRes = await api("createSurveyRecord", { - corpId: corpId, - userId: userId.value, - surveryId: survey._id, - memberId: customerId.value, - customer: customerName.value, - sendSurveyId: sendSurveyId, - teamId: teamId.value, - }); - - 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 + // 使用统一的消息发送助手 + const success = await sendSurveyMessage( + { + _id: survey._id, + name: survey.name || "问卷", + surveryId: survey.surveryId || survey._id, + url: survey.url || "", + }, + { + userId: userId.value, + customerId: customerId.value, + customerName: customerName.value, + corpId: corpId, + teamId: teamId.value, + } ); - // 构建自定义消息 - const customMessage = buildSurveyMessage(survey, sendLink); - - // 发送自定义消息到IM - const result = await timChatManager.sendCustomMessage( - customMessage, - "SURVEY" - ); - if (result.success) { + if (success) { uni.showToast({ title: "发送成功", icon: "success", @@ -407,8 +382,6 @@ const sendSurvey = async (survey) => { setTimeout(() => { uni.navigateBack(); }, 500); - } else { - throw new Error(result.error || "发送失败"); } } catch (error) { console.error("发送问卷失败:", error); diff --git a/pages/work/profile copy.vue b/pages/work/profile copy.vue index cde3235..dd6f598 100644 --- a/pages/work/profile copy.vue +++ b/pages/work/profile copy.vue @@ -71,7 +71,7 @@ @@ -110,7 +110,7 @@ const formData = ref({ department: "", departmentName: "", departmentId: "", - intro: "", + memberTroduce: "", }); // 选项数据 diff --git a/pages/work/profile.vue b/pages/work/profile.vue index 3124fa1..4e27069 100644 --- a/pages/work/profile.vue +++ b/pages/work/profile.vue @@ -2,97 +2,53 @@ - + - - - + + + - - + + - - - {{ jobStr }} - - - + + + + {{ jobStr }} + + + - - - - + + + {{ formData.title }} + + + - - + @@ -100,6 +56,7 @@