alibaba / ChatUI

The UI design language and React library for Conversational UI
https://chatui.io
MIT License
2.61k stars 277 forks source link

Chat UI Pro 查看历史消息的URL没有自动填充分页参数currentPage,pageSize #137

Open cn-Halo opened 5 months ago

cn-Halo commented 5 months ago

Version information (版本信息)

Describe the bug (描述问题) Chat UI Pro 查看历史消息的URL没有自动填充分页参数currentPage,pageSize

Steps To Reproduce (重现步骤) setup.js

// chartUI文档:https://chatui.io/docs/quick-start
var requestOcr = () => {
  return Promise.resolve({ res: { text: '123' } })
}
//获取userId
// const userId = uuid();
const userId = '123';

/**
 *  快捷回复短语
 */
var quickReplies = {
  type: 'quick-replies',
  content: {
    list: [
      {
        name: '申请成为经销商',
        isHighlight: true,
        type: 'url',
        url: '/home',
      }
    ]
  }
}

var myd = {
  position: 'center',
  type: 'card',
  content: {
    code: 'recommend',
    data: {
      hideShortcuts: true,
      list: [
        {
          title: '您对我们的服务满意吗?',
          text: '',
        },
        {
          title: '满意'
        },
        {
          title: '不满意'
        }
      ]
    }
  },
}

var bot = new ChatSDK({
  config: {
    // (可选)配置按钮文案
    loadMoreText: '点击加载更多',
    // (可选)进入页面时,是否自动触发加载历史消息操作
    autoLoadMore: true,
    // quickReplies: quickReplies,
    agent: {
      quickReply: {
        icon: 'message',
        name: '人工客服',
        isHighlight: true,
      },
    },
    navbar: {
      title: '智能助理'
    },
    robot: {
      avatar: 'http://gw.alicdn.com/tfs/TB1U7FBiAT2gK0jSZPcXXcKkpXa-108-108.jpg'
    },
    messages: [
      {
        type: 'text',
        content: {
          text: '智能助理为您服务,请问有什么可以帮您?'
        }
      }
    ],
    toolbar: [
      {
        type: 'image',
        icon: 'image',
        title: '相册',
      },
    ],
  },
  requests: {
    // 配置接口
    history: function (msg) {
      console.log('msg2', msg)
      return {
        url: 'http://localhost:9090/api/message/history',
      };
    },
    // send ask messgae
    send: function (msg) {
      if (msg.type === 'text') {
        return {
          url: 'http://localhost:9090/api/message/ask',
          data: {
            q: msg.content.text
          }
        };
      }
    }
  },

  makeSocket({ ctx }) {
    // 连接 ws
    const ws = new WebSocket('ws://localhost:9090/ws/' + userId);
    // 排队提示消息的ID
    let queueMsgId;

    ws.onerror = (e) => {
      console.log('websocket error', e)
    }

    // 当收到消息时
    ws.onmessage = (e) => {
      const data = JSON.parse(e.data);
      console.log('新消息到达', data)

      // // 展示排队消息
      // if (data.num) {
      //   // 如果界面上已经有排队消息则更新
      //   if (queueMsgId) {
      //     ctx.updateMessage(queueMsgId, {
      //       type: 'system',
      //       content: {
      //         text: `当前客服人数已满,您前面还有 ${data.num} 人`,
      //       },
      //     });
      //   } else {
      //     // 否则插入一条排队消息
      //     queueMsgId = '_queue_msg_id_';
      //     ctx.appendMessage({
      //       id: queueMsgId,
      //       type: 'system',
      //       content: {
      //         text: `当前客服人数已满,您前面还有 ${data.num} 人`,
      //       },
      //     });
      //   }
      //   return;
      // }

      // 移除排队消息
      // ctx.deleteMessage(queueMsgId);

      if (data.type === 'text') {
        const msg = {
          type: 'text',
          content: {
            text: data.content.text,
          },
          user: {
            avatar: 'https://gw.alicdn.com/tfs/TB1U7FBiAT2gK0jSZPcXXcKkpXa-108-108.jpg',
          },
        }
        // 展示消息内容
        ctx.appendMessage(msg);
      }

    };

    // 当结束服务的时候,提示用户
    ws.onclose = (e) => {
      console.log('ws close', e);
      ctx.appendMessage({
        type: 'system',
        content: {
          text: '人工客服已退出服务',
        },
      });

      /**********结束聊天后显示满意度调查*********** */
      ctx.appendMessage(myd);

      /**********结束聊天后显示满意度调查*********** */
      showQuickRelies(ctx)

    };

    // 当结束服务的时候,提示用户
    ws.onopen = (e) => {

      console.log('ws onopen', e);
      ctx.appendMessage({
        type: 'system',
        content: {
          text: '人工客服已进入服务',
        },
      });

      //发送一条心跳消息
      var ping = {
        "type": 'ping',
        "content": {
          "id": 0, //消息的id ,会话建立时为0, 每发一条消息 则自增
          "isTourist": 0, // 0是非游客,1是游客
          "avatar": 'https://gw.alicdn.com/tfs/TB1U7FBiAT2gK0jSZPcXXcKkpXa-108-108.jpg', //发送人的头像
          "userId": userId, //发送人的ID
          "nickname": '游客' + userId,
          "timestamp": getTimestamp(), //发送人的当地时间戳(10位 秒级)
          "timeZoneId": "GMT+8",//发送人当地的时区
        }
      }
      ws.send(JSON.stringify(ping));

      /**********显示结束聊天的按钮*********** */
      var command = {
        type: 'quick-replies',
        content: {
          list: [
            {
              name: '结束会话',
              type: 'cmd',
              cmd: { code: 'agent_leave' },
              isHighlight: true,
            }
          ]
        }
      }
      ctx.appendMessage(command)
      /**********显示结束聊天的按钮*********** */

    };

    return {
      // 把用户的信息发给后端
      send(msg) {
        /**
         * msg 当前的消息格式
         * {"type":"text","content":{"text":"234"},"position":"right","_id":"kgx3ri35c0j"}
         *
         * cim的消息格式
         * {"id":1711002493852,"action":"2","content":"123","sender":"system","receiver":"123","extra":"","title":"","format":"0","timestamp":1711002493852}
         *
         *
         */
        console.log('发送的消息', msg)

        if (msg.type === 'text') {
          msg = {
            type: 'text',
            content: {
              text: msg.content.text,
              isTourist: 0, // 0是非游客,1是游客
              avatar: null, //发送人的头像
              userId: userId, //发送人的ID
              toUserId: 1231231111111,
              appid: null,//扩展字段
              other: null,//扩展字段
              timestamp: getTimestamp(), //发送人的当地时间戳(10位 秒级)
              timeZoneId: "GMT+8",//发送人当地的时区
            }
          }
          // ws.send(JSON.stringify(message));
        }
        console.log('结构化之后的消息', message)
        postData("http://localhost:9090/api/messgae/user/send", msg).then((data) => {
          console.log(data); // JSON data parsed by `data.json()` call
        });
        // console.log('ws', ws);

      },
      close() {
        ws.close();
      },
    };
  },

  handlers: {
    onToolbarClick(item, ctx) {
      // 如果点的是“相册”
      if (item.type === 'image') {
        ctx.util.chooseImage({
          // multiple: true, // 是否可多选
          success(e) {
            if (e.files) { // 如果有 h5 上传的图
              const file = e.files[0];
              // 先展示图片
              ctx.appendMessage({
                type: 'image',
                content: {
                  picUrl: URL.createObjectURL(file)
                },
                position: 'right'
              });

              // 发起请求,具体自行实现,这里以 OCR 识别后返回文本为例
              requestOcr({ file }).then(res => {
                console.log('aa ', res)
                ctx.postMessage({
                  type: 'text',
                  content: {
                    text: 'res.text'
                  },
                  quiet: true // 不展示
                });
              });

            } else if (e.images) { // 如果有 app 上传的图
              // ..与上面类似
            }
          },
        });
      }
    }
  }

});

bot.run();
const ctx = bot.getCtx();
showQuickRelies(ctx);

console.log('bot', bot)

/**
 * 显示快捷短语
 */
function showQuickRelies(ctx) {
  ctx.appendMessage(quickReplies)
  //默认显示人工客服按钮
  ctx.appendMessage({
    type: 'cmd',
    content: {
      code: 'agent_entrance_display'
    }
  });
}

function uuid() {
  var temp_url = URL.createObjectURL(new Blob());
  var uuid = temp_url.toString(); // blob:https://xxx.com/b250d159-e1b6-4a87-9002-885d90033be3
  URL.revokeObjectURL(temp_url);
  return uuid.substr(uuid.lastIndexOf("/") + 1);
}

/**
 *  当前时间戳(10位)
 */
function getTimestamp() {
  let outcome = Number(Math.round(new Date().getTime() / 1000).toString());
  return outcome
}

// function sendHttpMessage() {
//   fetch("https://10.2.30.50:9090/chat/sendMessage")
//     .then(response => {
//       // indicates whether the response is successful (status code 200-299) or not
//       if (!response.ok) {

//       }
//       return response.json()
//     })
//     .then(data => {
//       console.log(data.count)
//       console.log(data.products)
//     })
//     .catch(error => console.log(error))
// }

/**
 * 发送http post请求
 * @param {} url 
 * @param {*} data 
 * @returns 
 */
async function postData(url = "", data = {}) {
  // Default options are marked with *
  const response = await fetch(url, {
    method: "POST", // *GET, POST, PUT, DELETE, etc.
    mode: "cors", // no-cors, *cors, same-origin
    cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
    credentials: "same-origin", // include, *same-origin, omit
    headers: {
      "Content-Type": "application/json",
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: "follow", // manual, *follow, error
    referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data), // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

// import jwt from 'jsonwebtoken';

// const jwt = require('jsonwebtoken');
// console.log('jwt... ', jwt)
// const secretKey = 'mysecretkey'; // 密

// const xhr = new XMLHttpRequest();
// xhr.open('POST', 'https://chatbot.weixin.qq.com/openapi/sign/LhNjthPCmPzGqDwCYGW95uyfxJEEyq');
// xhr.setRequestHeader('Content-Type', 'application/json');
// xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
// xhr.onload = () => {
//   if (xhr.status === 201) {
//     console.log(xhr.responseText);
//   } else {
//     console.error(`Error: ${xhr.status}`);
//   }
// };
// xhr.send(JSON.stringify({
//   username: 'John Doe',
//   userid: 'johndoe@example.com',
//   avatar: "https://res.wx.qq.com/a/wx_fed/weixin_portal/res/static/img/1L3ryyg.png"
// }));

Link to minimal reproduction (最小化重现链接)

Expected behavior (期望的结果是什么) 希望chatui pro能传递分页参数

cn-Halo commented 5 months ago

image

akai commented 2 days ago

你可以在 requests.history 返回的结果里加上 datadata 的数据得自己维护