Files
JoyD/Claw/client/wechat_app/pages/chat/chat.js
zqm cdf64fa31f feat(XCamera): 实现异步抓图功能并优化图像处理
fix(nginx): 调整企业微信回调代理路径

feat(gateway): 添加企业微信消息处理功能

docs: 更新项目规划文档和企业微信配置详情

refactor(XCamera): 重构LED检测和图像处理逻辑

test: 添加ONVIF抓图测试功能
2026-03-31 11:04:43 +08:00

419 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 聊天页面逻辑
const { API, WebSocketManager, util, constants } = require('../../utils/api.js')
const { formatRelativeTime } = util
const { MESSAGE_TYPE, WS_MESSAGE_TYPE } = constants
Page({
data: {
messages: [],
inputValue: '',
sending: false,
isTyping: false,
showHistoryTip: false,
websocketManager: null,
lastMessageId: '',
isConnected: false,
currentPage: 1
},
onLoad() {
this.initWebSocket()
this.loadChatHistory()
this.addWelcomeMessage()
},
onUnload() {
if (this.data.websocketManager) {
this.data.websocketManager.disconnect()
}
},
// 添加欢迎消息
addWelcomeMessage() {
const welcomeMessage = {
id: util.generateUniqueId(),
content: '你好我是智控未来的AI助手有什么可以帮你的吗',
type: MESSAGE_TYPE.TEXT,
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(welcomeMessage)
},
// 初始化WebSocket连接
initWebSocket() {
const manager = new WebSocketManager()
const app = getApp()
manager.onMessage(WS_MESSAGE_TYPE.MESSAGE, (data) => {
this.handleNewMessage(data)
})
manager.onMessage(WS_MESSAGE_TYPE.SYSTEM, (data) => {
this.handleSystemMessage(data)
})
manager.connect(app.globalData.websocketUrl || 'wss://pactgo.cn/api/v1/ws/control')
this.setData({
websocketManager: manager,
isConnected: true
})
},
// 加载聊天记录
async loadChatHistory() {
try {
// 模拟加载历史消息
const mockHistory = this.getMockHistoryMessages()
if (mockHistory.length > 0) {
this.setData({
messages: mockHistory,
showHistoryTip: true
})
this.scrollToBottom()
}
} catch (error) {
console.error('加载聊天记录失败:', error)
}
},
// 加载更多历史消息
loadMoreHistory() {
if (this.data.currentPage < 3) { // 模拟加载3页历史
this.setData({ currentPage: this.data.currentPage + 1 })
const moreHistory = this.getMockHistoryMessages(this.data.currentPage)
if (moreHistory.length > 0) {
const updatedMessages = [...moreHistory, ...this.data.messages]
this.setData({ messages: updatedMessages })
}
}
},
// 模拟历史消息
getMockHistoryMessages(page = 1) {
const messages = []
if (page === 1) {
messages.push({
id: 'history-1',
content: '你好我是智控未来的AI助手',
type: MESSAGE_TYPE.TEXT,
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: '昨天 14:30'
})
messages.push({
id: 'history-2',
content: '你能做什么?',
type: MESSAGE_TYPE.TEXT,
isMe: true,
nickname: '我',
avatar: '/assets/images/user-avatar.png',
time: '昨天 14:31'
})
messages.push({
id: 'history-3',
content: '我可以帮你解答问题、提供信息、生成内容等。请问有什么具体需求吗?',
type: MESSAGE_TYPE.TEXT,
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: '昨天 14:32'
})
} else if (page === 2) {
messages.push({
id: 'history-4',
content: '如何学习编程?',
type: MESSAGE_TYPE.TEXT,
isMe: true,
nickname: '我',
avatar: '/assets/images/user-avatar.png',
time: '昨天 15:00'
})
messages.push({
id: 'history-5',
content: '<p>学习编程的步骤:</p><ol><li>选择一门编程语言如Python、JavaScript等</li><li>学习基础语法和概念</li><li>实践项目,积累经验</li><li>参与社区,学习他人的代码</li></ol>',
type: MESSAGE_TYPE.richText,
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: '昨天 15:01'
})
}
return messages
},
// 处理新消息
handleNewMessage(data) {
this.setData({ isTyping: false })
// 模拟不同类型的消息
if (data.content.includes('代码')) {
const codeMessage = {
id: data.id || util.generateUniqueId(),
content: 'def hello():\n print("Hello, World!")',
type: 'code',
language: 'Python',
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(codeMessage)
} else if (data.content.includes('卡片')) {
const cardMessage = {
id: data.id || util.generateUniqueId(),
type: 'buttonCard',
title: '选择一个选项',
buttons: [
{ id: '1', text: '选项一', action: 'option1' },
{ id: '2', text: '选项二', action: 'option2' }
],
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(cardMessage)
} else if (data.content.includes('富文本')) {
const richTextMessage = {
id: data.id || util.generateUniqueId(),
content: '<h3>标题</h3><p>这是一段<b>加粗</b>的文本,包含<ul><li>无序列表项1</li><li>无序列表项2</li></ul></p>',
type: 'richText',
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(richTextMessage)
} else {
const message = {
id: data.id || util.generateUniqueId(),
content: data.content,
type: data.type || MESSAGE_TYPE.TEXT,
isMe: false,
nickname: data.nickname || '智控未来',
avatar: data.avatar || '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(message)
}
},
// 处理系统消息
handleSystemMessage(data) {
const message = {
id: data.id || util.generateUniqueId(),
content: data.content,
type: MESSAGE_TYPE.SYSTEM,
isMe: false,
nickname: '系统',
avatar: '/assets/images/system-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(message)
},
// 添加消息
addMessage(message) {
const messages = [...this.data.messages, message]
this.setData({
messages: messages,
lastMessageId: message.id
})
this.scrollToBottom()
},
// 滚动到底部
scrollToBottom() {
setTimeout(() => {
if (this.data.messages.length > 0) {
const lastMessage = this.data.messages[this.data.messages.length - 1]
this.setData({
lastMessageId: lastMessage.id
})
}
}, 100)
},
// 输入变化
onInputChange(e) {
this.setData({
inputValue: e.detail.value
})
},
// 发送消息
async sendMessage() {
const content = this.data.inputValue.trim()
if (!content || this.data.sending) {
return
}
this.setData({
sending: true,
isTyping: true
})
// 添加用户消息到界面
const userMessage = {
id: util.generateUniqueId(),
content: content,
type: MESSAGE_TYPE.TEXT,
isMe: true,
nickname: '我',
avatar: '/assets/images/user-avatar.png',
time: formatRelativeTime(new Date())
}
this.addMessage(userMessage)
try {
// 模拟AI回复
setTimeout(() => {
const aiResponse = {
id: util.generateUniqueId(),
content: this.getMockAIResponse(content),
type: MESSAGE_TYPE.TEXT,
isMe: false,
nickname: '智控未来',
avatar: '/assets/images/ai-avatar.png',
time: formatRelativeTime(new Date())
}
this.handleNewMessage(aiResponse)
}, 1500)
this.setData({
inputValue: '',
sending: false
})
} catch (error) {
console.error('发送消息失败:', error)
util.showError('发送失败,请重试')
this.setData({
sending: false,
isTyping: false
})
}
},
// 模拟AI回复
getMockAIResponse(content) {
const responses = {
'你好': '你好!很高兴为你服务。',
'今天天气怎么样': '今天天气晴朗,适合户外活动。',
'如何学习编程': '学习编程需要持之以恒,建议从基础语法开始,多动手实践。',
'代码': 'def hello():\n print("Hello, World!")',
'卡片': '这是一个卡片消息',
'富文本': '这是一段富文本消息,包含<b>加粗</b>和<u>下划线</u>。',
'今天是几月几日': '今天是' + new Date().toLocaleDateString('zh-CN'),
'你是谁': '我是智控未来的AI助手由LMStudio提供支持。'
}
return responses[content] || '感谢你的提问,我会为你提供准确的回答。'
},
// 长按消息
onMessageLongPress(e) {
const messageId = e.currentTarget.dataset.messageId
const message = this.data.messages.find(msg => msg.id === messageId)
if (message && message.type === MESSAGE_TYPE.TEXT) {
wx.showActionSheet({
itemList: ['复制消息', '删除消息'],
success: (res) => {
switch (res.tapIndex) {
case 0:
this.copyMessage(message.content)
break
case 1:
this.deleteMessage(messageId)
break
}
}
})
}
},
// 复制消息
copyMessage(content) {
wx.setClipboardData({
data: content,
success: () => {
wx.showToast({
title: '复制成功',
icon: 'success'
})
}
})
},
// 删除消息
deleteMessage(messageId) {
const updatedMessages = this.data.messages.filter(msg => msg.id !== messageId)
this.setData({ messages: updatedMessages })
wx.showToast({
title: '已删除',
icon: 'success'
})
},
// 复制代码
copyCode(e) {
const content = e.currentTarget.dataset.content
wx.setClipboardData({
data: content,
success: () => {
wx.showToast({
title: '代码已复制',
icon: 'success'
})
}
})
},
// 预览图片
previewImage(e) {
const url = e.currentTarget.dataset.url
wx.previewImage({
urls: [url]
})
},
// 卡片按钮点击
onCardButtonTap(e) {
const action = e.currentTarget.dataset.action
wx.showToast({
title: `你点击了${action}`,
icon: 'none'
})
},
// 清空聊天记录
clearChatHistory() {
wx.showModal({
title: '清空聊天记录',
content: '确定要清空所有聊天记录吗?此操作不可恢复。',
confirmText: '清空',
confirmColor: '#dd524d',
success: (res) => {
if (res.confirm) {
this.setData({
messages: [],
lastMessageId: ''
})
// 清空本地存储
wx.removeStorageSync('chatHistory')
wx.showToast({
title: '已清空',
icon: 'success'
})
}
}
})
}
})