diff --git a/src/app.json b/src/app.json index 619ccca..7021e8f 100644 --- a/src/app.json +++ b/src/app.json @@ -64,6 +64,12 @@ "resolveAlias": { "@/*": "/*" }, + "plugins": { + "WechatSI": { + "version": "0.3.7", + "provider": "wx069ba97219f66d99" + } + }, "usingComponents": { "navbar": "/components/navbar/index" }, diff --git a/src/custom-tab-bar/index.ts b/src/custom-tab-bar/index.ts index 6e7e024..7f46c91 100644 --- a/src/custom-tab-bar/index.ts +++ b/src/custom-tab-bar/index.ts @@ -71,7 +71,7 @@ Component({ // 获取通知未读数 async fetchUnreadCount() { try { - await app.waitLogin({ type: 1 }) + await app.waitLogin({ type: 0 }) const res = await wx.ajax({ url: '/notification/unread-count', method: 'GET', diff --git a/src/pages/chat/index.json b/src/pages/chat/index.json index ed567fe..f77574c 100644 --- a/src/pages/chat/index.json +++ b/src/pages/chat/index.json @@ -1,7 +1,12 @@ { "navigationBarTitleText": "智能助手", + "requiredPrivateInfos": ["getRecorderManager"], + "permission": { + "scope.record": { + "desc": "需要使用你的麦克风进行语音识别" + } + }, "usingComponents": { "van-icon": "@vant/weapp/icon/index" } } - diff --git a/src/pages/chat/index.scss b/src/pages/chat/index.scss index eeaa48f..59a17c3 100644 --- a/src/pages/chat/index.scss +++ b/src/pages/chat/index.scss @@ -18,10 +18,14 @@ page { /* ========== 聊天消息列表 ========== */ .chat-scroll { flex: 1; + min-height: 0; + overflow: hidden; position: relative; - padding: 160rpx 28rpx 0; - box-sizing: border-box; + padding: 0 28rpx 0; box-sizing: border-box; + .scroll-top-safe { + height: 160px; + } .history { width: 167rpx; @@ -70,6 +74,7 @@ page { font-size: 32rpx; color: #fff; line-height: 56rpx; + word-break: break-all; } .ai-message { clear: both; @@ -82,6 +87,7 @@ page { color: rgba(71, 85, 105, 1); background-color: #fff; border-radius: 24rpx; + word-break: break-all; .high { display: inline; color: rgba(74, 184, 253, 1); @@ -90,7 +96,7 @@ page { } .scroll-bottom-safe { clear: both; - height: 223rpx; + height: 283rpx; } } @@ -105,6 +111,19 @@ page { border-radius: 95rpx; background-color: #fff; box-shadow: 0px 15px 30px 0px rgba(0, 96, 143, 0.09); + .go-act-draft { + position: absolute; + top: -20rpx; + left: 0; + padding: 12rpx 28rpx; + transform: translateY(-100%); + font-size: 32rpx; + color: rgba(71, 85, 105, 1); + border-radius: 69rpx; + box-shadow: 0rpx 11rpx 21rpx 0rpx rgba(0, 96, 143, 0.09); + background: linear-gradient(0deg, #ffffff 0%, #f8fdff 100%); + line-height: 44rpx; + } .freetext { padding-left: 26rpx; height: 100%; @@ -113,6 +132,22 @@ page { .input { flex: 1; } + .send-btn { + flex-shrink: 0; + width: 56rpx; + height: 56rpx; + border-radius: 50%; + background: rgba(226, 232, 240, 1); + display: flex; + align-items: center; + justify-content: center; + margin-right: 10rpx; + color: #fff; + &--active { + background: linear-gradient(135deg, #9ddffd 0%, #4ab8fd 100%); + color: #fff; + } + } .icon { padding-left: 26rpx; flex-shrink: 0; @@ -137,7 +172,11 @@ page { height: 60rpx; } } + .voice--hidden { + visibility: hidden; + } .voiceing { + margin: 0 -18rpx; padding: 213rpx 0 0; position: fixed; left: 0; diff --git a/src/pages/chat/index.ts b/src/pages/chat/index.ts index 82e0be0..99fec34 100644 --- a/src/pages/chat/index.ts +++ b/src/pages/chat/index.ts @@ -1,12 +1,16 @@ /** - * Chat 聊天页面 + * Chat 聊天页面 — 活动智能体交互 */ +const app = getApp() +const plugin = requirePlugin('WechatSI') +const recognitionManager = plugin.getRecordRecognitionManager() interface Message { id: string - role: 'user' | 'ai' - content: string - timestamp: number + type: 'u_msg' | 'a_msg' + role: 'user' | 'agent' + msg: string + time: string } Page({ @@ -17,52 +21,109 @@ Page({ inputText: '', /** 输入模式:text 或 voice */ inputMode: 'voice' as 'text' | 'voice', - /** 是否正在录音 */ + /** 是否正在录音识别 */ isRecording: false, /** 录音提示文本 */ - recordingTip: '松手发送,上移取消', - /** 录音管理器 */ - recorderManager: null as WechatMiniprogram.RecorderManager | null, + recordingTip: '松手结束,上移取消', + /** 是否取消本次识别 */ + cancelled: false, /** 滚动到指定消息 */ scrollToView: '', - /** 页面顶部距离 */ - pageTop: 0, - /** 导航栏背景 */ - background: 'transparent', + /** 当前会话ID,为空则新建 */ + sessionId: '', + /** 是否正在等待AI回复 */ + sending: false, + /** 接口返回的活动ID,有值时显示草稿入口 */ + activityId: '', }, - onLoad() { - // 初始化录音管理器 - const recorderManager = wx.getRecorderManager() - recorderManager.onStart(() => { - this.setData({ isRecording: true, recordingTip: '松手发送,上移取消' }) - }) - recorderManager.onStop((res) => { + _sessionId: '', + + onLoad(options: Record) { + const sessionId = options.session_id || '' + this._sessionId = sessionId + this.setData({ sessionId }) + + // 语音识别回调 + recognitionManager.onStart = () => { + this.setData({ cancelled: false, recordingTip: '松手结束,上移取消' }) + } + recognitionManager.onStop = (res: any) => { this.setData({ isRecording: false }) - if (res.duration < 1000) { - wx.showToast({ title: '录音时间太短', icon: 'none' }) - return + if (this.data.cancelled) return + const result = (res.result || '').trim() + if (result) { + const separator = this.data.inputText ? ' ' : '' + this.setData({ inputText: this.data.inputText + separator + result, inputMode: 'text' }) } - // 发送语音消息 - this.sendVoiceMessage(res.tempFilePath, res.duration) - }) - recorderManager.onError((err) => { + } + recognitionManager.onError = (err: any) => { this.setData({ isRecording: false }) - wx.showToast({ title: '录音失败', icon: 'none' }) - console.error('录音错误:', err) + if (err.errCode === -30003) return + wx.showToast({ title: '语音识别失败', icon: 'none' }) + } + + // 登录后加载历史 + app.waitLogin({ type: 1 }).then(() => { + if (sessionId) { + this.loadSessionDetail(sessionId) + } }) - this.setData({ recorderManager }) + }, + + /** 从 a_msg 的 msg 字段中提取展示文本(可能为 JSON 字符串) */ + parseAgentMsg(raw: string): string { + if (!raw) return '' + try { + const obj = JSON.parse(raw) + if (obj && typeof obj.msg === 'string') return obj.msg + } catch {} + return raw + }, - // 获取系统信息设置页面顶部距离 - const systemInfo = wx.getSystemInfoSync() - this.setData({ pageTop: systemInfo.statusBarHeight + 44 }) + /** 从接口33加载会话详情(历史消息) */ + async loadSessionDetail(sessionId: string) { + try { + const res = await wx.ajax({ + url: '/session/detail', + method: 'GET', + data: { session_id: sessionId }, + }) + if (res && res.messages) { + const messages = this.handleRemoveFirstMessage(res.messages).map((m: Message) => ({ + ...m, + msg: m.type === 'a_msg' ? this.parseAgentMsg(m.msg) : m.msg, + })) + this.setData({ messages }) + } + if (res?.session?.activityId) { + this.setData({ activityId: res.session.activityId }) + } + this.scrollToBottom() + } catch (err) { + console.error('加载会话详情失败:', err) + } }, - /** - * 切换到语音模式 - */ + handleRemoveFirstMessage(messages: Message[]): Message[] { + if (messages.length === 0) return messages + return messages.slice(1) + }, + + /** 点击"最近对话"按钮 */ + goHistory() { + wx.navigateTo({ url: '/pages/chatHistory/index' }) + }, + + /** 点击"查看当前草稿"按钮 */ + goActDraft() { + if (this.data.activityId) { + wx.navigateTo({ url: `/pages/actAdd/index?id=${this.data.activityId}` }) + } + }, + + /** 切换到语音模式 */ switchToVoice() { - // 如果 input 有内容,不允许切换到语音模式 if (this.data.inputText.trim()) { wx.showToast({ title: '请先发送或清空内容', icon: 'none' }) return @@ -70,181 +131,185 @@ Page({ this.setData({ inputMode: 'voice' }) }, - /** - * 切换到文本模式 - */ + /** 切换到文本模式 */ switchToText() { this.setData({ inputMode: 'text' }) }, - /** - * 输入框内容变化 - */ - onInputChange(e: WechatMiniprogram.InputEvent) { + /** 输入框内容变化 */ + onInputChange(e: any) { this.setData({ inputText: e.detail.value }) }, - /** - * 发送文本消息 - */ + /** 发送文本消息 */ onSendText() { - const { inputText } = this.data - if (!inputText.trim()) return + const { inputText, sending } = this.data + if (!inputText.trim() || sending) return + this.doInteract(inputText.trim()) + }, - // 添加用户消息 + /** 调用接口31: 活动智能体交互 */ + async doInteract(uMsg: string) { + this.setData({ sending: true, inputText: '' }) + + // 先将用户消息追加到列表 const userMessage: Message = { - id: `user_${Date.now()}`, + id: `temp_u_${Date.now()}`, + type: 'u_msg', role: 'user', - content: inputText.trim(), - timestamp: Date.now(), + msg: uMsg, + time: this.formatTime(new Date()), } - this.setData({ - messages: [...this.data.messages, userMessage], - inputText: '', - }) + const messages = [...this.handleRemoveFirstMessage(this.data.messages), userMessage] + this.setData({ messages }) + this.scrollToBottom() - // 模拟 AI 回复 - this.simulateAIResponse() - }, + try { + const reqData: Record = { u_msg: uMsg } + if (this._sessionId) { + reqData.session_id = this._sessionId + } - /** - * chat-input 区域长按开始录音 - */ - onChatInputLongPress() { - // 文本模式下有内容时,不允许录音 - if (this.data.inputMode === 'text' && this.data.inputText.trim()) { - wx.showToast({ title: '请先发送或清空内容', icon: 'none' }) - return - } + const res = await wx.ajax({ + url: '/activity/interact', + method: 'POST', + data: reqData, + }) - const { recorderManager } = this.data - if (!recorderManager) return + // 更新sessionId + if (res.session?.session_id) { + this._sessionId = res.session.session_id + this.setData({ sessionId: res.session.session_id }) + } - recorderManager.start({ - duration: 60000, - sampleRate: 16000, - numberOfChannels: 1, - encodeBitRate: 48000, - format: 'mp3', - }) - }, + // 内容不合规提示 + if (res.resp === 'RESP_ILLEGAL') { + wx.showToast({ title: '内容不合规,请重新输入', icon: 'none' }) + this.setData({ sending: false }) + return + } - /** - * chat-input 区域触摸开始 - */ - onChatInputStart() { - // 用于检测长按,不做实际操作 - // 长按逻辑由 bindlongpress 处理 - }, - - /** - * chat-input 区域触摸结束 - */ - onChatInputEnd() { - const { recorderManager, isRecording } = this.data - if (!recorderManager || !isRecording) return - recorderManager.stop() - }, - - /** - * chat-input 区域触摸取消 - */ - onChatInputCancel() { - const { recorderManager, isRecording } = this.data - if (!recorderManager || !isRecording) return - recorderManager.stop() - this.setData({ isRecording: false, recordingTip: '录音已取消' }) - wx.showToast({ title: '录音已取消', icon: 'none' }) - }, - - /** - * voiceing 区域触摸移动(检测手指是否移出) - */ - onVoiceingTouchMove(e: WechatMiniprogram.TouchEvent) { - const { isRecording, recordingTip } = this.data - if (!isRecording) return - - // 获取触摸点位置 - const touch = e.touches[0] - const systemInfo = wx.getSystemInfoSync() - const screenHeight = systemInfo.screenHeight - - // voiceing 区域高度为 448rpx,约 224px - // 当手指 Y 坐标小于 (屏幕高度 - voiceing高度) 时,说明手指移出了区域 - const voiceingHeight = 224 // 448rpx ≈ 224px - const threshold = screenHeight - voiceingHeight - - if (touch.clientY < threshold) { - // 手指移出区域,准备取消 - if (recordingTip !== '上移取消录音') { - this.setData({ recordingTip: '上移取消录音' }) + // 提取活动ID + if (res.data.activity_id) { + this.setData({ activityId: res.data.activity_id }) } - } else { - // 手指在区域内,恢复提示 - if (recordingTip !== '松手发送,上移取消') { - this.setData({ recordingTip: '松手发送,上移取消' }) + + // 用服务端返回的消息列表替换 + if (res.session && res.session.msg) { + const messages = this.handleRemoveFirstMessage(res.session.msg).map((m: Message) => ({ + ...m, + msg: m.type === 'a_msg' ? this.parseAgentMsg(m.msg) : m.msg, + })) + this.setData({ messages }) } - } - }, - /** - * voiceing 区域触摸结束 - */ - onVoiceingTouchEnd(e: WechatMiniprogram.TouchEvent) { - const { recorderManager, isRecording, recordingTip } = this.data - if (!recorderManager || !isRecording) return - - // 获取触摸点位置 - const changedTouch = e.changedTouches[0] - const systemInfo = wx.getSystemInfoSync() - const screenHeight = systemInfo.screenHeight - const voiceingHeight = 224 // 448rpx ≈ 224px - const threshold = screenHeight - voiceingHeight - - // 如果手指移出区域,取消录音 - if (changedTouch.clientY < threshold || recordingTip === '上移取消录音') { - recorderManager.stop() - this.setData({ isRecording: false, recordingTip: '录音已取消' }) - wx.showToast({ title: '录音已取消', icon: 'none' }) - } else { - // 手指在区域内,正常结束录音并发送 - recorderManager.stop() + this.scrollToBottom() + } catch (err: any) { + // AI服务异常时,服务端可能返回session_id用于重试 + if (err?.data?.session_id) { + this._sessionId = err.data.session_id + this.setData({ sessionId: err.data.session_id }) + } + wx.showToast({ title: '发送失败,请重试', icon: 'none' }) + } finally { + this.setData({ sending: false }) } }, - /** - * 发送语音消息 - */ - sendVoiceMessage(filePath: string, duration: number) { - const userMessage: Message = { - id: `user_${Date.now()}`, - role: 'user', - content: `[语音 ${Math.ceil(duration / 1000)}秒]`, - timestamp: Date.now(), - } - this.setData({ - messages: [...this.data.messages, userMessage], + /** 重置当前会话 */ + resetSession() { + if (!this._sessionId) return + + wx.showModal({ + title: '提示', + content: '确定要重置当前对话吗?', + success: async (res) => { + if (!res.confirm) return + try { + await wx.ajax({ + url: '/activity/interact', + method: 'POST', + data: { + session_id: this._sessionId, + reset: true, + }, + }) + this._sessionId = '' + this.setData({ sessionId: '', messages: [], activityId: '' }) + wx.showToast({ title: '已重置', icon: 'success' }) + } catch { + wx.showToast({ title: '重置失败', icon: 'none' }) + } + }, }) + }, - // 模拟 AI 回复 - this.simulateAIResponse() + /** 格式化时间 */ + formatTime(date: Date): string { + const pad = (n: number) => n.toString().padStart(2, '0') + return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` }, - /** - * 模拟 AI 回复 - */ - simulateAIResponse() { + /** 滚动到底部 */ + scrollToBottom() { setTimeout(() => { - const aiMessage: Message = { - id: `ai_${Date.now()}`, - role: 'ai', - content: '好的,我已经收到您的消息,正在为您处理中...', - timestamp: Date.now(), - } - this.setData({ - messages: [...this.data.messages, aiMessage], + this.setData({ scrollToView: 'scroll-bottom-safe' }) + }, 100) + }, + + /** 阻止滚动穿透 */ + preventTouchMove() {}, + + // ===== 语音识别相关 ===== + onVoiceTouchStart() {}, + onVoiceLongPress() { + wx.authorize({ scope: 'scope.record' }) + .then(() => { + this.setData({ isRecording: true, cancelled: false, recordingTip: '松手结束,上移取消' }) + recognitionManager.start({ lang: 'zh_CN' }) }) - }, 1000) + .catch(() => { + wx.showModal({ + title: '提示', + content: '需要录音权限才能使用语音输入,是否前往设置开启?', + success: (res) => { + if (res.confirm) wx.openSetting() + }, + }) + }) + }, + + isAboveCancelZone(clientY: number) { + const { screenHeight } = wx.getWindowInfo() + return clientY < screenHeight - 224 + }, + + onVoiceTouchMove(e: WechatMiniprogram.TouchEvent) { + if (!this.data.isRecording) return + const above = this.isAboveCancelZone(e.touches[0].clientY) + const tip = above ? '松手取消识别' : '松手结束,上移取消' + if (this.data.recordingTip !== tip) { + this.setData({ recordingTip: tip }) + } + }, + + onVoiceTouchEnd(e: WechatMiniprogram.TouchEvent) { + if (!this.data.isRecording) return + const cancel = this.isAboveCancelZone(e.changedTouches[0].clientY) || this.data.recordingTip === '松手取消识别' + if (cancel) { + this.setData({ cancelled: true, inputText: '', isRecording: false, recordingTip: '识别已取消' }) + recognitionManager.stop() + wx.showToast({ title: '识别已取消', icon: 'none' }) + } else { + recognitionManager.stop() + } + }, + + onVoiceTouchCancel() { + if (!this.data.isRecording) return + this.setData({ cancelled: true, inputText: '', isRecording: false, recordingTip: '识别已取消' }) + recognitionManager.stop() + wx.showToast({ title: '识别已取消', icon: 'none' }) }, }) diff --git a/src/pages/chat/index.wxml b/src/pages/chat/index.wxml index f39a5ce..18283b6 100644 --- a/src/pages/chat/index.wxml +++ b/src/pages/chat/index.wxml @@ -3,64 +3,69 @@ style="background: url('{{imageUrl}}bg3.png?t={{Timestamp}}') no-repeat top center/100% 556rpx;padding-top: {{pageTop}}px;" > - + - 最近对话 + + 最近对话 你好呀~我是你的活动创建小助手你可以直接告诉我想创建什么活动,比如 - “下周五下午3点在报告厅办一场心理健康讲座” + "下周五下午3点在报告厅办一场心理健康讲座" 我会帮你自动整理活动信息。 - 特别说明:内容均为ai生成,仅供参考 + 特别说明:内容均为ai生成,仅供参考 - - 请帮我创建一个下周活动,活动主题是新生音乐会,活动地点是学校音乐厅 - - 信息我已经整理好~我还需要再确认一点信息: - 您的活动打算什么时候开始呢?告诉我开始和结束的时间,我来帮您创建~ + + {{item.msg}} + + + {{item.msg}} + - + - + + 查看当前草稿 - + - - + + 按住说话 - + - + {{recordingTip}} diff --git a/src/pages/chatHistory/index.json b/src/pages/chatHistory/index.json index 9e257b4..3d75104 100644 --- a/src/pages/chatHistory/index.json +++ b/src/pages/chatHistory/index.json @@ -1,5 +1,9 @@ { "navigationBarTitleText": "最近对话", "navigationStyle": "default", - "usingComponents": {} + "enablePullDownRefresh": true, + "usingComponents": { + "van-icon": "@vant/weapp/icon/index", + "van-loading": "@vant/weapp/loading/index" + } } diff --git a/src/pages/chatHistory/index.scss b/src/pages/chatHistory/index.scss index b9c7d1c..3bc6804 100644 --- a/src/pages/chatHistory/index.scss +++ b/src/pages/chatHistory/index.scss @@ -1,29 +1,100 @@ page { background-color: rgba(247, 248, 250, 1); } + .page { padding: 30rpx; - .card { - padding: 32rpx; - background-color: #fff; - border-radius: 24rpx; - display: flex; - gap: 24rpx; - .wrap { - .title { - font-size: 36rpx; - color: rgba(17, 24, 39, 1); - line-height: 56rpx; - } - .date{ - margin-top: 14rpx; - font-size: 32rpx; - color: rgba(148, 163, 184, 1); - } + padding-bottom: 180rpx; + min-height: 100vh; + box-sizing: border-box; +} + +.card { + padding: 32rpx; + background-color: #fff; + border-radius: 24rpx; + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24rpx; + + .wrap { + flex: 1; + min-width: 0; + + .title { + font-size: 36rpx; + color: rgba(17, 24, 39, 1); + line-height: 56rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .desc { + margin-top: 14rpx; + font-size: 28rpx; + color: rgba(148, 163, 184, 1); } - .status{ - font-size: 32rpx; + } + + .meta { + flex-shrink: 0; + display: flex; + align-items: center; + gap: 12rpx; + + .count { + font-size: 28rpx; color: rgba(203, 213, 225, 1); } } } + +.empty { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 240rpx; + + .empty-text { + font-size: 32rpx; + color: rgba(148, 163, 184, 1); + } + + .empty-btn { + margin-top: 40rpx; + padding: 18rpx 64rpx; + background: linear-gradient(90deg, #9ddffd 0%, #4ab8fd 100%); + color: #fff; + font-size: 32rpx; + border-radius: 54rpx; + } +} + +.loading { + display: flex; + justify-content: center; + padding: 40rpx 0; +} + +.no-more { + text-align: center; + padding: 30rpx 0; + font-size: 28rpx; + color: rgba(203, 213, 225, 1); +} + +.fab { + position: fixed; + right: 40rpx; + bottom: 120rpx; + width: 100rpx; + height: 100rpx; + border-radius: 50%; + background: linear-gradient(135deg, #9ddffd 0%, #4ab8fd 100%); + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 8rpx 24rpx rgba(74, 184, 253, 0.35); +} diff --git a/src/pages/chatHistory/index.ts b/src/pages/chatHistory/index.ts index 067b6bb..3d7fc71 100644 --- a/src/pages/chatHistory/index.ts +++ b/src/pages/chatHistory/index.ts @@ -1,8 +1,119 @@ -const _app = getApp(); +const app = getApp() + +interface ChatSession { + session_id: string + uid: string + agent_type: string + title: string + last_message: string + last_time: string + created_at: string + msg_count: number +} Page({ - data: {}, - onLoad() {}, -}); + data: { + list: [] as ChatSession[], + total: 0, + offset: 0, + limit: 20, + loading: false, + noMore: false, + }, + + onLoad() { + app.waitLogin({ type: 1 }).then(() => { + this.fetchList(true) + }) + }, + + onPullDownRefresh() { + this.fetchList(true).then(() => { + wx.stopPullDownRefresh() + }) + }, + + onReachBottom() { + if (this.data.loading || this.data.noMore) return + this.fetchList() + }, + + async fetchList(refresh = false) { + if (this.data.loading) return + + const offset = refresh ? 0 : this.data.offset + this.setData({ loading: true }) + + try { + const res = await wx.ajax({ + url: '/session/list', + method: 'GET', + data: { + agent_type: 'activity', + limit: this.data.limit, + offset, + }, + }) + + const newList = res.list || [] + const total = res.total || 0 + const list = refresh ? newList : [...this.data.list, ...newList] + + this.setData({ + list, + total, + offset: offset + newList.length, + noMore: list.length >= total, + }) + } catch (err) { + console.error('获取会话列表失败:', err) + } finally { + this.setData({ loading: false }) + } + }, + + /** 点击会话卡片,跳转到聊天页恢复会话 */ + onTapSession(e: WechatMiniprogram.TouchEvent) { + const { sessionId } = e.currentTarget.dataset + wx.navigateTo({ url: `/pages/chat/index?session_id=${sessionId}` }) + }, + + /** 删除会话 */ + onLongPressSession(e: WechatMiniprogram.TouchEvent) { + const { sessionId, index } = e.currentTarget.dataset + + wx.showModal({ + title: '提示', + content: '确定要删除该对话吗?', + success: async (res) => { + if (!res.confirm) return + + try { + await wx.ajax({ + url: '/activity/interact', + method: 'POST', + data: { + session_id: sessionId, + reset: true, + }, + }) + + wx.showToast({ title: '删除成功', icon: 'success' }) + const list = [...this.data.list] + list.splice(index, 1) + const total = this.data.total - 1 + this.setData({ list, total }) + } catch (err: any) { + wx.showToast({ title: '删除失败', icon: 'none' }) + } + }, + }) + }, + + /** 新建对话 */ + onCreateChat() { + wx.navigateTo({ url: '/pages/chat/index' }) + }, +}) export {} diff --git a/src/pages/chatHistory/index.wxml b/src/pages/chatHistory/index.wxml index d102406..5847df6 100644 --- a/src/pages/chatHistory/index.wxml +++ b/src/pages/chatHistory/index.wxml @@ -1,9 +1,37 @@ - - - 新生音乐会 - 2026/6/15 + + + + {{item.title || '新对话'}} + {{item.last_time}} + + + {{item.msg_count}}条对话 + + - 草稿 + + + + 暂无对话记录 + 发起对话 + + + + 加载中... + + + 没有更多了 + + +