| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- // pages/chat/chat.js
- const chatApi = require('../../api/chat');
- const userUtil = require('../../utils/user');
- Page({
- data: {
- userId: null,
- sessionId: null,
- messages: [],
- inputMessage: '',
- loading: false,
- sending: false,
- scrollIntoView: '' // 用于scroll-view滚动到底部
- },
- onLoad(options) {
- console.log('聊天页面加载, options:', options);
-
- const userInfo = userUtil.getUserInfo();
- console.log('用户信息:', userInfo);
-
- if (!userInfo || !userInfo.userId) {
- console.error('用户未登录或userId为空');
- wx.showToast({
- title: '请先登录',
- icon: 'none'
- });
- setTimeout(() => {
- wx.navigateBack();
- }, 1500);
- return;
- }
- console.log('设置userId:', userInfo.userId);
- this.setData({
- userId: userInfo.userId
- });
- // 优先使用传入的sessionId(如果有)
- if (options.sessionId) {
- console.log('使用传入的sessionId:', options.sessionId);
- this.setData({
- sessionId: options.sessionId
- });
- // 保存sessionId到本地存储
- this.saveSessionId(options.sessionId);
- this.loadMessageHistory();
- } else {
- // 尝试从本地存储加载sessionId
- const savedSessionId = this.getSavedSessionId(userInfo.userId);
- if (savedSessionId) {
- console.log('从本地存储加载sessionId:', savedSessionId);
- this.setData({
- sessionId: savedSessionId
- });
- this.loadMessageHistory();
- } else {
- // 创建新会话
- console.log('创建新会话');
- this.createSession();
- }
- }
- },
-
- onShow() {
- // 检查用户是否仍然登录
- const userInfo = userUtil.getUserInfo();
- if (!userInfo || !userInfo.userId) {
- // 用户已退出登录,清除会话数据
- if (this.data.sessionId) {
- this.clearSavedSessionId(this.data.userId);
- }
- return;
- }
-
- // 如果userId发生变化(可能是切换了账号),重新加载
- if (this.data.userId && userInfo.userId !== this.data.userId) {
- console.log('检测到用户切换,重新加载会话');
- this.setData({
- userId: userInfo.userId,
- sessionId: null,
- messages: []
- });
- const savedSessionId = this.getSavedSessionId(userInfo.userId);
- if (savedSessionId) {
- this.setData({ sessionId: savedSessionId });
- this.loadMessageHistory();
- } else {
- this.createSession();
- }
- }
- },
- // 创建新会话
- async createSession() {
- try {
- console.log('开始创建会话, userId:', this.data.userId);
- if (!this.data.userId) {
- throw new Error('userId为空,请先登录');
- }
-
- this.setData({ loading: true });
- const session = await chatApi.createSession(this.data.userId);
- console.log('创建会话成功:', session);
-
- if (!session || !session.sessionId) {
- throw new Error('创建会话失败,未返回sessionId');
- }
-
- // 保存sessionId到本地存储
- this.saveSessionId(session.sessionId);
-
- this.setData({
- sessionId: session.sessionId,
- messages: [],
- loading: false
- });
- console.log('会话创建完成, sessionId:', session.sessionId);
- } catch (error) {
- console.error('创建会话失败:', error);
- wx.showToast({
- title: '创建会话失败: ' + (error.message || error),
- icon: 'none',
- duration: 2000
- });
- this.setData({ loading: false });
- throw error; // 重新抛出错误,让调用方知道失败
- }
- },
-
- // 保存sessionId到本地存储
- saveSessionId(sessionId) {
- if (!this.data.userId || !sessionId) {
- return;
- }
- const key = `chat_sessionId_${this.data.userId}`;
- wx.setStorageSync(key, sessionId);
- console.log('保存sessionId到本地存储:', key, sessionId);
- },
-
- // 从本地存储获取sessionId
- getSavedSessionId(userId) {
- if (!userId) {
- return null;
- }
- const key = `chat_sessionId_${userId}`;
- const sessionId = wx.getStorageSync(key);
- console.log('从本地存储获取sessionId:', key, sessionId);
- return sessionId || null;
- },
-
- // 清除本地存储的sessionId
- clearSavedSessionId(userId) {
- if (!userId) {
- return;
- }
- const key = `chat_sessionId_${userId}`;
- wx.removeStorageSync(key);
- console.log('清除本地存储的sessionId:', key);
- },
- // 加载消息历史
- async loadMessageHistory() {
- if (!this.data.sessionId || !this.data.userId) {
- console.warn('无法加载消息历史:sessionId或userId为空');
- return;
- }
-
- try {
- this.setData({ loading: true });
- console.log('加载消息历史:', this.data.sessionId, this.data.userId);
- const messages = await chatApi.getMessageHistory(this.data.sessionId, this.data.userId);
- console.log('收到消息历史:', messages);
-
- // 确保消息格式正确(处理时间戳)
- const formattedMessages = (messages || []).map(msg => {
- return {
- role: msg.role || 'user',
- content: msg.content || '',
- timestamp: msg.timestamp || new Date().toISOString()
- };
- });
-
- this.setData({
- messages: formattedMessages,
- loading: false
- });
-
- // 延迟滚动到底部,确保DOM已更新
- setTimeout(() => {
- this.scrollToBottom();
- }, 200);
- } catch (error) {
- console.error('加载消息历史失败:', error);
- // 如果是会话不存在或无权访问,清除本地保存的sessionId
- if (error.message && (error.message.includes('不存在') || error.message.includes('无权访问'))) {
- console.log('会话无效,清除本地保存的sessionId');
- this.clearSavedSessionId(this.data.userId);
- this.setData({
- sessionId: null,
- messages: []
- });
- // 创建新会话
- this.createSession();
- } else {
- wx.showToast({
- title: '加载消息失败',
- icon: 'none'
- });
- this.setData({ loading: false });
- }
- }
- },
- // 输入消息
- onInput(e) {
- this.setData({
- inputMessage: e.detail.value
- });
- },
- // 发送消息
- async sendMessage() {
- const message = this.data.inputMessage.trim();
- if (!message) {
- wx.showToast({
- title: '请输入消息',
- icon: 'none'
- });
- return;
- }
- // 检查userId
- if (!this.data.userId) {
- console.error('userId为空,请先登录');
- wx.showToast({
- title: '请先登录',
- icon: 'none'
- });
- return;
- }
- // 如果没有sessionId,先创建会话
- if (!this.data.sessionId) {
- console.log('没有sessionId,创建新会话');
- try {
- await this.createSession();
- if (!this.data.sessionId) {
- wx.showToast({
- title: '创建会话失败',
- icon: 'none'
- });
- return;
- }
- } catch (error) {
- console.error('创建会话失败:', error);
- wx.showToast({
- title: '创建会话失败: ' + error,
- icon: 'none',
- duration: 2000
- });
- return;
- }
- }
- try {
- this.setData({
- sending: true,
- inputMessage: ''
- });
- console.log('开始发送消息:', {
- sessionId: this.data.sessionId,
- userId: this.data.userId,
- message: message
- });
- // 添加用户消息到列表
- const userMessage = {
- role: 'user',
- content: message,
- timestamp: new Date().toISOString()
- };
- const currentMessages = [...this.data.messages, userMessage];
- this.setData({
- messages: currentMessages
- });
- this.scrollToBottom();
- // 发送消息到服务器
- console.log('调用API发送消息...');
- const response = await chatApi.sendMessage(this.data.sessionId, message, this.data.userId);
- console.log('收到API响应:', response);
-
- // 更新会话ID(如果是新创建的)
- if (response.session && response.session.sessionId) {
- const newSessionId = response.session.sessionId;
- console.log('更新sessionId:', newSessionId);
- this.setData({
- sessionId: newSessionId
- });
- // 保存新的sessionId到本地存储
- this.saveSessionId(newSessionId);
- }
- // 添加AI回复到列表
- if (response.assistantMessage) {
- console.log('收到AI回复:', response.assistantMessage.content);
- this.setData({
- messages: [...currentMessages, response.assistantMessage]
- });
- this.scrollToBottom();
- } else {
- console.warn('未收到AI回复');
- wx.showToast({
- title: '未收到AI回复',
- icon: 'none'
- });
- }
- this.setData({ sending: false });
- } catch (error) {
- console.error('发送消息失败:', error);
- console.error('错误详情:', JSON.stringify(error));
- wx.showToast({
- title: '发送失败: ' + (error.message || error || '未知错误'),
- icon: 'none',
- duration: 3000
- });
- // 移除用户消息(发送失败)
- const messages = this.data.messages.filter(m => m.content !== message || m.role !== 'user');
- this.setData({
- messages: messages,
- sending: false,
- inputMessage: message
- });
- }
- },
- // 滚动到底部
- scrollToBottom() {
- // 使用scroll-view的scroll-into-view属性滚动到底部
- if (this.data.messages && this.data.messages.length > 0) {
- const lastIndex = this.data.messages.length - 1;
- const scrollIntoView = `msg-${lastIndex}`;
- this.setData({
- scrollIntoView: scrollIntoView
- });
- // 清除scrollIntoView,以便下次可以再次触发
- setTimeout(() => {
- this.setData({
- scrollIntoView: ''
- });
- }, 300);
- }
- },
- // 格式化时间
- formatTime(date) {
- if (!date) return '';
- try {
- const d = typeof date === 'string' ? new Date(date) : date;
- if (isNaN(d.getTime())) return '';
- const hours = d.getHours().toString().padStart(2, '0');
- const minutes = d.getMinutes().toString().padStart(2, '0');
- return `${hours}:${minutes}`;
- } catch (e) {
- return '';
- }
- }
- });
|