From 327148260ce210f3a38e2edfcb15a77a94963ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=98=E9=A3=8E?= Date: Wed, 14 Jan 2026 15:18:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B7=9F=E8=BF=9B=E6=8F=90?= =?UTF-8?q?=E9=86=92=E5=92=8C=E5=BE=85=E5=8A=9E=E4=BA=8B=E9=A1=B9=E7=9B=B8?= =?UTF-8?q?=E5=85=B3API=EF=BC=8C=E4=BC=98=E5=8C=96=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=87=E6=9C=AC=E6=8F=92=E5=85=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E3=80=82=E6=9B=B4=E6=96=B0=E7=BB=84=E4=BB=B6=E4=BB=A5?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E7=94=A8=E6=88=B7=E4=BA=A4=E4=BA=92=E4=BD=93?= =?UTF-8?q?=E9=AA=8C=EF=BC=8C=E7=A1=AE=E4=BF=9D=E8=BE=93=E5=85=A5=E6=A1=86?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=B5=81=E7=95=85=E3=80=82=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E6=96=B0=E7=BB=84=E4=BB=B6=E4=BB=A5=E5=A4=84=E7=90=86=E5=BF=AB?= =?UTF-8?q?=E6=8D=B7=E5=9B=9E=E5=A4=8D=E5=92=8C=E6=B6=88=E6=81=AF=E9=A2=84?= =?UTF-8?q?=E8=A7=88=EF=BC=8C=E6=8F=90=E5=8D=87=E6=95=B4=E4=BD=93=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TouchVueThree/src/api/modules/wechat.ts | 74 +++ TouchVueThree/src/components.d.ts | 1 + .../modules/wechat/useChatWindowStore.ts | 23 + .../components/ChatHeader/index.vue | 66 +-- .../components/FollowUpReminder/index.vue | 357 ++++++++++++ .../components/MessageInput/index.vue | 78 ++- .../ProfileCard/components/QuickReply.vue | 526 +++++++++++++++++- .../ChatWindow/components/TodoList/index.vue | 383 +++++++++++++ 8 files changed, 1417 insertions(+), 91 deletions(-) create mode 100644 TouchVueThree/src/views/Chat/components/ChatWindow/components/FollowUpReminder/index.vue create mode 100644 TouchVueThree/src/views/Chat/components/ChatWindow/components/TodoList/index.vue diff --git a/TouchVueThree/src/api/modules/wechat.ts b/TouchVueThree/src/api/modules/wechat.ts index 660052b..2e9e849 100644 --- a/TouchVueThree/src/api/modules/wechat.ts +++ b/TouchVueThree/src/api/modules/wechat.ts @@ -578,3 +578,77 @@ export function searchChatRecords(params: { }) { return request('/v1/wechat/message/search', params, 'POST') } + +// ==================== 跟进提醒相关接口 ==================== + +/** + * 获取跟进提醒列表 + */ +export function getFollowUpList(params: { + isProcess?: string + isRemind?: string + keyword?: string + level?: string + limit?: string + page?: string + friendId?: string +}) { + return request('/v1/kefu/followUp/list', params, 'GET') +} + +/** + * 添加跟进提醒 + */ +export function addFollowUp(params: { + description?: string + friendId: string + reminderTime?: string + title?: string + type?: string // 0其他 1电话回访 2发送消息 3安排会议 4发送邮件 +}) { + return request('/v1/kefu/followUp/add', params, 'POST') +} + +/** + * 处理跟进提醒 + */ +export function processFollowUp(params: { ids?: string }) { + return request('/v1/kefu/followUp/process', params, 'GET') +} + +// ==================== 待办事项相关接口 ==================== + +/** + * 获取待办事项列表 + */ +export function getTodoList(params: { + isProcess?: string + isRemind?: string + keyword?: string + level?: string + limit?: string + page?: string + friendId?: string +}) { + return request('/v1/kefu/todo/list', params, 'GET') +} + +/** + * 添加待办事项 + */ +export function addTodo(params: { + description?: string + friendId: string + level?: string // 0低优先级 1中优先级 2高优先级 3紧急 + reminderTime?: string + title?: string +}) { + return request('/v1/kefu/todo/add', params, 'POST') +} + +/** + * 处理待办事项 + */ +export function processTodo(params: { ids: string }) { + return request('/v1/kefu/todo/process', params, 'GET') +} diff --git a/TouchVueThree/src/components.d.ts b/TouchVueThree/src/components.d.ts index 88ec263..20184a6 100644 --- a/TouchVueThree/src/components.d.ts +++ b/TouchVueThree/src/components.d.ts @@ -16,6 +16,7 @@ declare module 'vue' { ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition'] ElContainer: typeof import('element-plus/es')['ElContainer'] + ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDialog: typeof import('element-plus/es')['ElDialog'] ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] diff --git a/TouchVueThree/src/stores/modules/wechat/useChatWindowStore.ts b/TouchVueThree/src/stores/modules/wechat/useChatWindowStore.ts index 40a6d1a..6f90d98 100644 --- a/TouchVueThree/src/stores/modules/wechat/useChatWindowStore.ts +++ b/TouchVueThree/src/stores/modules/wechat/useChatWindowStore.ts @@ -28,6 +28,9 @@ export const useChatWindowStore = defineStore('chat-window', () => { /** 当前输入内容 */ const inputContent = ref('') + /** 待插入的内容(用于快捷语等功能) */ + const pendingInsertContent = ref('') + /** 草稿箱(按会话ID存储) */ const drafts = ref>(new Map()) @@ -133,6 +136,23 @@ export const useChatWindowStore = defineStore('chat-window', () => { // ==================== 输入框操作 ==================== + /** + * 插入文本到输入框 + * + * @param content 要插入的内容 + */ + const insertText = (content: string) => { + pendingInsertContent.value = content + console.log(`📝 插入文本到输入框: ${content.substring(0, 50)}...`) + } + + /** + * 清空待插入内容 + */ + const clearPendingInsert = () => { + pendingInsertContent.value = '' + } + /** * 保存草稿 * @@ -232,6 +252,7 @@ export const useChatWindowStore = defineStore('chat-window', () => { // 输入框状态 inputContent, + pendingInsertContent, currentDraft, // AI 配置 @@ -247,6 +268,8 @@ export const useChatWindowStore = defineStore('chat-window', () => { closeTodoList, // 输入框操作 + insertText, + clearPendingInsert, saveDraft, loadDraft, clearDraft, diff --git a/TouchVueThree/src/views/Chat/components/ChatWindow/components/ChatHeader/index.vue b/TouchVueThree/src/views/Chat/components/ChatWindow/components/ChatHeader/index.vue index 53b4286..463101d 100644 --- a/TouchVueThree/src/views/Chat/components/ChatWindow/components/ChatHeader/index.vue +++ b/TouchVueThree/src/views/Chat/components/ChatWindow/components/ChatHeader/index.vue @@ -7,7 +7,11 @@ - {{ currentSession?.nickname?.charAt(0) || currentSession?.conRemark?.charAt(0) || '?' }} + {{ + currentSession?.nickname?.charAt(0) || + currentSession?.conRemark?.charAt(0) || + '?' + }} @@ -16,9 +20,7 @@ {{ displayName }}
- - 群聊 - + 群聊 在线 @@ -37,62 +39,56 @@ - + - - - - - + - +
+ + + + + + + + diff --git a/TouchVueThree/src/views/Chat/components/ChatWindow/components/MessageInput/index.vue b/TouchVueThree/src/views/Chat/components/ChatWindow/components/MessageInput/index.vue index e9f41a9..0d26295 100644 --- a/TouchVueThree/src/views/Chat/components/ChatWindow/components/MessageInput/index.vue +++ b/TouchVueThree/src/views/Chat/components/ChatWindow/components/MessageInput/index.vue @@ -41,23 +41,14 @@
- - - + + + - +
@@ -172,8 +163,8 @@ import { Picture, Microphone, Location, - MagicStick, - Search, + Share, + ChatLineSquare, Promotion, Loading, CircleClose, @@ -195,7 +186,7 @@ const messageStore = useMessageStore() const chatWindowStore = useChatWindowStore() const { currentSession } = storeToRefs(sessionStore) -const { aiLoading } = storeToRefs(messageStore) +const { pendingInsertContent } = storeToRefs(chatWindowStore) // ==================== WebSocket ==================== const { sendCommand } = useWebSocket() @@ -839,24 +830,19 @@ const handleConfirmLocation = async () => { } /** - * AI 辅助点击 + * 转给他人点击 */ -const handleAIClick = async () => { - if (!inputRef.value) return - const text = htmlToText(inputRef.value.innerHTML).trim() - if (!text || !currentSession.value) return - - try { - await messageStore.requestAIReply(text) - // TODO: 显示 AI 回复建议 - ElMessage.info('AI 辅助功能开发中...') - } catch (error) { - console.error('AI 辅助失败:', error) +const handleTransferClick = () => { + if (!currentSession.value) { + ElMessage.warning('请先选择会话') + return } + // TODO: 实现转接功能 + ElMessage.info('转接功能开发中...') } /** - * 搜索点击 + * 聊天记录点击 */ const handleSearchClick = () => { chatWindowStore.openChatHistory() @@ -902,6 +888,40 @@ watch( { immediate: true } ) +/** + * 监听待插入内容(用于快捷语等功能) + */ +watch(pendingInsertContent, (newContent) => { + if (newContent && inputRef.value) { + // 插入文本到输入框 + const selection = window.getSelection() + const range = selection?.getRangeAt(0) + + if (range && inputRef.value.contains(range.commonAncestorContainer)) { + // 在光标位置插入文本 + const textNode = document.createTextNode(newContent) + range.deleteContents() + range.insertNode(textNode) + + // 移动光标到插入文本之后 + range.setStartAfter(textNode) + range.setEndAfter(textNode) + selection?.removeAllRanges() + selection?.addRange(range) + } else { + // 如果没有选区,追加到末尾 + inputRef.value.textContent += newContent + } + + // 更新输入内容 + handleInput() + // 聚焦输入框 + inputRef.value.focus() + // 清空待插入内容 + chatWindowStore.clearPendingInsert() + } +}) + /** * 组件挂载时加载草稿 */ diff --git a/TouchVueThree/src/views/Chat/components/ChatWindow/components/ProfileCard/components/QuickReply.vue b/TouchVueThree/src/views/Chat/components/ChatWindow/components/ProfileCard/components/QuickReply.vue index 1b1f073..0ef73cf 100644 --- a/TouchVueThree/src/views/Chat/components/ChatWindow/components/ProfileCard/components/QuickReply.vue +++ b/TouchVueThree/src/views/Chat/components/ChatWindow/components/ProfileCard/components/QuickReply.vue @@ -25,8 +25,12 @@ @@ -48,16 +52,18 @@ node-key="key" @node-click="handleNodeClick" > -