diff --git a/pages.json b/pages.json index d985437..34a8be8 100644 --- a/pages.json +++ b/pages.json @@ -279,6 +279,12 @@ "style": { "navigationBarTitleText": "执行回访计划" } + }, + { + "path": "followup-task-list", + "style": { + "navigationBarTitleText": "回访任务" + } } ] } diff --git a/pages/case/archive-detail.vue b/pages/case/archive-detail.vue index f3d7761..e5766e8 100644 --- a/pages/case/archive-detail.vue +++ b/pages/case/archive-detail.vue @@ -121,6 +121,7 @@ :archiveId="archiveId" :reachBottomTime="reachBottomTime" :floatingBottom="floatingBottom" + :fromChat="fromChat" /> @@ -242,6 +243,7 @@ const tabs = [ const currentTab = ref('visitRecord'); const reachBottomTime = ref(0); const archiveId = ref(''); +const fromChat = ref(false); const tabsScrollTop = ref(0); const instanceProxy = getCurrentInstance()?.proxy; @@ -474,6 +476,7 @@ async function updateArchive(patch) { onLoad((options) => { archiveId.value = options?.id ? String(options.id) : String(archive.value.medicalRecordNo || archive.value.outpatientNo || archive.value.inpatientNo || ''); + fromChat.value = options?.fromChat === 'true' || options?.fromChat === true; const cached = uni.getStorageSync(STORAGE_KEY); if (cached && typeof cached === 'object') { 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 9832d11..8cb1d49 100644 --- a/pages/case/components/archive-detail/follow-up-manage-tab.vue +++ b/pages/case/components/archive-detail/follow-up-manage-tab.vue @@ -33,7 +33,7 @@ - + 计划日期: {{ i.planDate }} {{ i.executorName }}({{ i.executeTeamName }}) @@ -45,7 +45,13 @@ {{ i.taskContent || '暂无内容' }} 【处理结果】 {{ i.result || '' }} - 创建: {{ i.createTimeStr }} {{ i.creatorName }} + + 创建: {{ i.createTimeStr }} {{ i.creatorName }} + + + + + @@ -146,6 +152,7 @@ const props = defineProps({ archiveId: { type: String, default: '' }, reachBottomTime: { type: [String, Number], default: '' }, floatingBottom: { type: Number, default: 16 }, + fromChat: { type: Boolean, default: false }, }); const accountStore = useAccountStore(); @@ -390,6 +397,29 @@ function toDetail(todo) { uni.navigateTo({ url: `/pages/case/followup-detail?archiveId=${encodeURIComponent(props.archiveId)}&mode=edit&id=${encodeURIComponent(todo._id)}` }); } +function sendFollowUp(todo) { + const content = `【回访计划】\n类型: ${todo.eventTypeLabel}\n计划日期: ${todo.planDate}\n执行人: ${todo.executorName}\n内容: ${todo.taskContent || '暂无内容'}`; + + // 触发事件,通知父组件发送消息 + uni.$emit('send-followup-message', { + content, + followupId: todo._id, + followupData: todo + }); + + // 获取当前页面栈 + const pages = getCurrentPages(); + const currentPage = pages[pages.length - 1]; + + // 如果当前页面是 followup-task-list,则返回两次(返回到消息页面) + if (currentPage && currentPage.route === 'pages/case/followup-task-list') { + uni.navigateBack({ delta: 2 }); + } else { + // 否则只返回一次 + uni.navigateBack(); + } +} + // ---- filter popup ---- const filterPopupRef = ref(null); const state = ref(null); @@ -625,10 +655,60 @@ watch( font-size: 13px; color: #666; } -.footer { +.footer-row { + display: flex; + align-items: center; + justify-content: space-between; margin-top: 10px; + padding-top: 10px; + border-top: 1px solid #f2f2f2; + gap: 10px; +} +.footer { font-size: 12px; color: #999; + flex: 1; +} +.footer-row .send-btn { + flex: 0 0 auto; + width: 60px; + height: 28px; + line-height: 28px; + padding: 0; + margin: 0; +} + +.card-actions { + display: flex; + gap: 10px; + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid #f2f2f2; +} + +.action-btn { + flex: 1; + height: 32px; + line-height: 32px; + border-radius: 6px; + font-size: 12px; + border: none; + background: #f5f6f8; + color: #333; +} + +.action-btn::after { + border: none; +} + +.detail-btn { + background: #f5f6f8; + color: #333; +} + +.send-btn { + background: #0877F1; + color: #fff; } .empty { diff --git a/pages/case/followup-task-list.vue b/pages/case/followup-task-list.vue new file mode 100644 index 0000000..14440f0 --- /dev/null +++ b/pages/case/followup-task-list.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/pages/message/article-list.vue b/pages/message/article-list.vue index 2954537..9f7576a 100644 --- a/pages/message/article-list.vue +++ b/pages/message/article-list.vue @@ -315,6 +315,8 @@ const closePreview = () => { const sendArticle = async (article) => { try { const { doctorInfo } = useAccountStore(); + + // 1. 调用后端API记录发送 const result = await api("sendArticleMessage", { groupId: pageParams.value.groupId, fromAccount: doctorInfo.userid, @@ -323,8 +325,46 @@ const sendArticle = async (article) => { 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 api("addArticleSendRecord", { articleId: article._id, diff --git a/pages/message/chat.scss b/pages/message/chat.scss index 83bb6a9..06cc9a9 100644 --- a/pages/message/chat.scss +++ b/pages/message/chat.scss @@ -430,6 +430,15 @@ $primary-color: #0877F1; box-sizing: border-box; line-height: 1.5; color: #333; + display: flex; + align-items: center; + justify-content: center; +} + +.text-input { + padding: 16rpx 46rpx; + display: block; + line-height: 1.5; } .voice-input-btn { diff --git a/pages/message/components/chat-input.vue b/pages/message/components/chat-input.vue index c48da5e..391e1bf 100644 --- a/pages/message/components/chat-input.vue +++ b/pages/message/components/chat-input.vue @@ -9,7 +9,7 @@