0


ChatUI 快速构建聊天 机器人为例:

ChatUI 主要分为 ChatUI 和 ChatPro 两部分(两套ui框架) 。

ChatUI 更适合手机应用

ChatPro 更适合浏览器页面对话(客服 虽然ChatUI对项目框架做了自适应尺寸 多端应用考虑较多 现实操作起来麻烦)

ChatUI 只支持React

不支持vue和小程序 (我在uni-app里尝试过使用 但不建议)因为ChatUI 框架本身使用的React 框架所以这就解释了为啥只按照要求使用React来引入ChatUI。

引入项目

import React, { useEffect, useRef } from 'react';

export default () => {
  const wrapper = useRef();

  useEffect(() => {
    const bot = new window.ChatSDK({
      root: wrapper.current,
      // 注册组件 仅在组件内使用
      components: {},
      config: { 
        // 机器人头像
        robot: {
          avatar: '//gw.alicdn.com/tfs/TB1U7FBiAT2gK0jSZPcXXcKkpXa-108-108.jpg',
        },
        // 用户头像
        user: {
          avatar: '//gw.alicdn.com/tfs/TB1DYHLwMHqK1RjSZFEXXcGMXXa-56-62.svg',
        },
        //(可选)配置按钮文案
        loadMoreText: '查看历史对话',
        // 反馈点赞
        feedback: {
          // 点赞后出的文本
          textOfGood: '谢谢您给我的赞,我会继续努力。',
          // 点踩后出的文本
          textOfBad: '',
          // 点踩后是否显示反馈表单
          needFeedback: true,
          // 不满意原因列表
          options: [
            {
              // 选项值
              value: '1',
            },
            {
              value: '2',
            },
            {
              value: '3',
            },
          ],
        },
       //快捷短语
       quickReplies: [
          { name: '张三', type: 'text', },
          { name: '李四' },
          { name: '王五',isNew: true, }
       ],
      }
      //输入框占位符
      placeholder: '请输入你的问题....',
      },
      //通讯请求(问答 反馈 历史 上传文件等)
      requests: {
        //问答
        send: function (msg) {},
        //历史配置接口 
        history: function () {},
        //点赞 踩赞
        evaluate(data) {},
        //反馈
        feedback(data) {},
      }
      //上传图片 文件等
      handlers: {}
    });

    bot.run();
  }, []);

  // 注意 wrapper 的高度
  return <div style={{ height: '100%' }} ref={wrapper} />;
}

requests 通讯请求(问答 反馈 历史 上传文件)

对话

项目中给我们封装的请求我不太喜欢 我使用的是Axios中文文档 | Axios中文网(axios)

requests: {
        /*
         *
         * 问答接口
         * @param {object} msg - 消息
         * @param {string} msg.type - 消息类型
         * @param {string} msg.content - 消息内容
         * @return {object}
         */
        send: function (msg) {
          // 发送文本消息时
          if (msg.type === 'text') {
            const payload = {
              query: XXXX,
            }
            //post请求
            return axios.post('/XXX', payload, {
              headers: {
                'Content-Type': 'application/json',
              },
            })
              .then(response => {
                  return (
                    {
                      //消息类型:text普通消息 默认文本
                      type: 'text',
                      //消息内容
                      content: {
                        text: response.data.output
                      }
                    }
                  );
              })
              .catch(error => {
                // 请求出错,处理错误
                console.error(error);
                // 返回错误信息或执行其他操作
                throw error;
              });
          }
          // ... 其它消息类型的处理
        },
      },

反馈(点赞功能)

不管点赞还是踩赞都是这一个接口 可以根据变量来区别传递内容(好/坏)

 evaluate(data) {
       return axios.post('/xxx',{messageId:xxx,}).then(res => {
       // 反馈文本(可以不管或antd轻提示) 
    })
 },

历史

历史的注意点在于 返回的结果 分清楚左右 时间处理问题等

//请求
      requests: {
        /**
         *
         * 问答接口
         * @param {object} msg - 消息
         * @param {string} msg.type - 消息类型
         * @param {string} msg.content - 消息内容
         * @return {object}
         */
        // 历史配置接口 
        history: function () {
          return axios.post('/XXX').then(res => {
            const historylist = res.data.historylist
            // *map需要返回值 记得暴露
            let list = historylist.map(item => {
              if (item.position == "left") {
                return {
                  //回复类型(文本样式)自己制作的组件
                  "type": 'TestQuestion',
                  //卡片
                  "code": 'knowledge',
                  "_id": "msg_1",
                  "position": item.position,
                  //文本内容
                  "content": {
                  //文本
                    "text": item.text
                  },
                  //时间处理
                  "createdAt": item.datetime
                }
              } else {
                return {
                  "_id": "msg_1",
                  "type": "text",
                  "position": item.position,
                  "content": {
                    "text": item.text
                  },
                  //时间处理 拿到的是时间戳(具体的数值)
                  "createdAt": item.datetime
                }
              }
            })
            return {
              list: list,
              "noMore": true
            }
          }
          ).catch(
            // message.success("正在加载....")
          )
        },
      },

上传(图片 文件)

//上传图片 文件等
      handlers: {
        onToolbarClick(item, ctx) {
          //如果点的是"相册"
          if (item.type === 'image') {
            ctx.util.chooseImage({
              multiple: true, // 是否可多选
              success(e) {
                if (e.files) { // 如果有 h5 上传的图
                  const file = e.files[0];
                  //文件流上传
                  const formData = new FormData();
                  formData.append("file", file)
                  //先展示图片
                  ctx.appendMessage({
                    type: 'image',
                    content: {
                      picUrl: URL.createObjectURL(file)
                    },
                    position: 'right'
                  });
                  return axios.post('/XXX', formData, {
                    headers: {
                      'Content-Type': 'multipart/form-data'
                    }
                  }).then(res => {
                    ctx.postMessage({
                      type: 'text',
                      content: {
                        text: res.data
                      },
                      quiet: true // 不展示
                    });
                  })
                } else if (e.files) { // 如果有 app 上传的图
                  // ..与上面类似
                }
              },
            });
          } 
        }
      }

图标

框架中有些ui图标缺失仔细查看使用的是 iconfont-阿里巴巴矢量图标库 其中的一种引用方式(ChatUI框架是阿里达摩院创作)可根据F12找到相关图标代码路径 然后在indext文件引入

<!-- chatui pro 组件icon资源丢失,底层代码是引入内部阿里的阿里适量需使用Symbol引入链接 -->
例如:
<script src="https://at.alicdn.com/t/c/font_4148071_nlz31z9a4y.js"></script>

封装组件(根据自己需求制作卡片)

参考Markdown 对话展示方式 那个就是自己写的组件(卡片)因为此组件只是将传递数据比较简单没做别的操作(使用的是函数组件)

注册卡片(组件)

使用以前要注册(引入组件)

一定要注意 ChatUI是用React开发的就意味着 只要将此UI框架引入我们的React项目就会有两个React版本(我们项目一个,ChatUI框架内核一个)ChatUI框架是用17^版本 我们要么保持一至 要么使用 class组件 否则项目会出现报错。

class组件官方正在弃用 只是在大力推广函数式组件

components: {
    "TestQuestion": Testquestion,
},

使用卡片

return {
   //使用卡片(组件)
   type: 'Testquestion',
   content: {
      //给卡片传递的数据(文本)
      text: res.data,
   }
}

Markdown 对话展示方式

使用React自带markdown组件需要自己安装(下面代码没有使用css说明使用了安装库只需要把文本传入组件即可)由于react自带的markdown功能没有那么全 需要自己去找合适库不一定要用React自带的。

文章属于回忆录

ChatUI用户群”群的钉钉群号: 32174470


本文转载自: https://blog.csdn.net/zhihuishuxia__/article/details/137467871
版权归原作者 zhihuishuxia__ 所有, 如有侵权,请联系我们删除。

“ChatUI 快速构建聊天 机器人为例:”的评论:

还没有评论