2.2.7 • Published 4 months ago

@itshixun/qchat v2.2.7

Weekly downloads
-
License
-
Repository
-
Last release
4 months ago

@itshixun/qchat

1. 快速集成

1.1 QChat对象

QChat类的创建参数定义如下:

/**
 * 创建QChat实例所需的参数类型
 * @template  T - 聊天场景类型SceneType,比如学生做作业、看课件、教师常规对话 等等
 * @template  U - 聊天类型ChatType,对应dify工作流各分支类型,比如StudentQa、TeacherQa、Courseware等
 */
export interface CreateQChatParams<T extends string, U extends string> {
  /** QChat初始选项 */
  initialOption: QChatOption<T, U>;
  /** 选项映射表,每个场景类型对应一个预设的选项对象,方便切换场景时快速变更选项 */
  optionsMap?: QChatSceneOptionMap<T, U>;
}

QChat对象通过单例工厂模式确保全局唯一实例。同时QChat具备延迟初始化特性:首次调用 getInstance() 时才创建实例,比如在React或Vue的App入口组件处,在组件mount后执行getInstance()方法创建实例。

1.2 创建QChat对象

// qchatController.ts

import { getToken } from './your/getToken/method';
import { QChat, type QChatOption } from '@itshixun/qchat';

const initialOption: QChatOption<string, string> = {
  defaultChatType: 'standard',
  server: {
    type: 'api',
    api: {
      url: 'https://api.example.com/chat',
      token: getToken,
      tokenKey: 'X-Access-Token',
    },
  },
};

export const qchat = new QChat<string, string>({ initialOption });

1.3 React 项目集成

// App.tsx (React 项目入口文件)

import { qchat } from 'qchatController';

// 获取实例并挂载
useEffect(() => {
  // 首次调用getInstance()时创建qchat组件实例
  const instance = qchat.getInstance();
  // 在应用入口显式挂载
  qchat.mount('qchat_container', 'qchat_btn');
  return () => {
    // 也可用qchat.dispose(),dispose方法也是调用了instance.unmount()
    instance.unmount();
  };
}, []);

return (
  <div>
    <div>{/* 主项目内容 */}</div>
    <div id="qchat-container" className="h-600px w-400px" />
    {/* qchat悬浮按钮需要放置在position-fixed的容器内,同时要注意控制zIndex,保持在所有内容的上层 */}
    <div id="qchat-btn" class="fixed w-0 h-0 z-9999" />
  </div>
);

1.4 Vue 项目集成

<!-- App.vue (Vue 项目入口文件) -->

<script setup>
  import { qchat } from 'qchatController';

  onMounted(() => {
    // 首次调用getInstance()时创建qchat组件实例
    qchat.getInstance();
    // 在应用入口显式挂载
    qchat.mount('qchat_container', 'qchat_btn');
  });

  onBeforeUnmount(() => {
    qchat.dispose();
  });
</script>

<template>
  <div><!-- 主项目内容 --></div>
  <div id="qchat-container" class="h-600px w-400px" />
  <!-- qchat悬浮按钮需要放置在position:fixed的容器内,同时要注意控制zIndex,保持在所有内容的上层 -->
  <div id="qchat-btn" class="fixed w-0 h-0 z-9999" />
</template>

1.5 类型安全体系

QChat 接受两个范型参数,详见1.1 中QChat 参数类型的定义。使用方式见下方代码示例:

import { QChat, QChatSceneOptionMap } from '@itshixun/qchat';

// 使用示例:定义教学场景类型和对话类型
type SceneType = 'lecture' | 'homework';
type ChatType = 'student' | 'teacher';

const optionsMap: QChatSceneOptionMap<SceneType, ChatType> = new Map<SceneType, Partial<QChatOption<ChatType>>>([
  [
    'lecture',
    {
      ui: {
        title: '教学助手',
      },
      /* ... */
    },
  ],
  [
    'homework',
    {
      ui: {
        title: '作业助手',
      },
      /* ... */
    },
  ],
]);

const eduChat = new QChat<SceneType, ChatType>({
  initialOption: {
    /* 初始基础配置项 */
  },
  optionsMap,
  containerId: 'qchat_container',
  btnId: 'qchat_btn',
});

// 在业务端,通过setOptionsFromKey方法,快速切换为对应场景的配置项
eduChat.getInstance().setOptionsFromKey('lecture', {
  /* 这里可附加额外配置项 */
});

2. 核心配置项

2.1 基础配置

2.1.1 配置项类型定义

/**
 * QChat组件配置项
 * QChat功能的核心类型,用于组件的配置项,包括外观配置、服务连接配置、相关状态等
 */
export interface QChatOption<SceneType extends string, ChatType extends string> {
  /** 外观配置 */
  ui?: {
    /** AI助手面板标题 */
    title?: string;
    /** AI助手面板logo */
    logo?: string;
    /** AI助手面板logo大小,默认34 */
    logoSize?: number;
    /** 显示关闭按钮 */
    showClose?: boolean;
    /** 欢迎界面配置 */
    welcome?: {
      title?: string;
      /** 欢迎页描述 */
      description?: string;
      /** 常用工具FUT(Frequently Used Tools)板块配置  */
      futConfig?: FUTConfig;
      /** 高频问题FAQ(Frequently Asked Questions)板块配置 */
      faqConfig?: FAQConfig;
    };
    /** 对话界面配置 */
    chat?: {
      /** 对话时显示双方名称 */
      showName?: boolean;
      /** 对话时显示双方头像 */
      showAvatar?: boolean;
      /** 底部是否显示类似“所有内容均由Ai生成仅供参考”的信息*/
      showBottomInfo?: boolean;
      /** 底部文字信息,默认“所有内容均由AI生成仅供参考” */
      bottomInfo?: string;
      /** ai助手头像 */
      aiAvatar?: string;
      /** ai助手名称 */
      aiName?: string;
      /** 用户头像 */
      userAvatar?: string;
      /** 用户名 */
      userName?: string;
      /** 头像大小 */
      avatarSize?: number;
      /** 输入框占位文字 */
      placeholderText?: string;
      /** 限制输入框和对话气泡列表的最大宽度,默认980px,传0则不限制 */
      maxChatWidth?: number;
      /** 输入框最大输入内容,不传则默认5000 */
      maxInputLength?: number;
      /** 可给对话容器附加样式 */
      chatWrapperStyle?: React.CSSProperties;
      /** 可给Header附加额外样式 */
      headerStyle?: React.CSSProperties;
      /** 抽屉样式 */
      drawerStyle?: React.CSSProperties;
    };
    /** ai按钮配置*/
    aiButton?: {
      /** 按钮可拖拽的区域,默认整个屏幕区域:top: 0, right: 0, bottom: 0, left: 0 */
      top?: number;
      right?: number;
      bottom?: number;
      left?: number;
      zIndex?: number;
      /** ai按钮的tooltip */
      tip?: string[];
    };
  };
  /**
   * 默认聊天类型,随着教师/学生等角色切换可随时改变
   */
  defaultChatType: ChatType;
  /**
   * 是否开启对话中的智能提示功能,默认为true,开启后,AI回复完内容后,会加载建议问题列表
   */
  enableChatSuggestions?: boolean;
  /**
   * 是否显示历史记录,默认为true,开启后,点击历史记录按钮,会加载历史记录列表
   */
  enableHistory?: boolean;
  /**
   * qst-ui-system 配置选项
   *
   *- `initQstTheme`决定是否在组件挂载时初始化 qst-ui-system 的样式(注入CSS 变量)。
   *- 如果容器项目已经初始化了 qst-ui-system:
   *   - 如果希望使用容器项目的qst-ui-system配置,`initQstTheme`设置为 `false`,并确保 `themeOption.namespace` 与容器项目一致,组件将使用容器项目的 UI 主题配置。
   *   - 如果需要与容器项目使用不同的 qst-ui-system 配置:`initQstTheme`设置为`true`,且必须设置 `themeOption.namespace` 和 `themeOption.styleTagId`,以与容器项目的配置区分开。
   *- 如果容器项目未使用 qst-ui-system:
   *   - `initQstTheme`必须设置为 `true`,组件将在挂载时根据 `themeOption` 初始化 qst-ui-system 并注入样式。
   */
  theme?: {
    namespace: string;
    initQstTheme?: boolean;
    themeOption?: ThemeOption;
  };
  /**
   * qchat相关状态,跟随页面使用场景的变化而更新
   */
  state?: QChatState<SceneType, ChatType>;
  /** 服务连接配置 */
  server: ServerOptions;
}

/**
 * qchat组件状态配置
 */
export interface QChatState<SceneType extends string, ChatType extends string> {
  /** 当前所在课程id */
  courseId?: string;
  /**
   * 场景,比如“答疑、课件学习、作业辅助、练习辅助、实践学习”,每次提问带场景参数,用于统计
   * - CourseQA(1, "课程答疑"),
   * - PreviewCourseware(2, "课件预览"),
   * - HomeworkAnswer(3, "作业答题"),
   * - ExerciseAnswer(4, "练习答题"),
   * - DoExperiment(5, "做实验"),
   * - DoPractice(6, "做实训"),
   */
  scene?: SceneType;
  /**
   * 在active状态如果为true,则显示对话面板,否则隐藏对话面板,显示悬浮按钮。
   */
  active?: boolean;
  /**
   * 建议问题列表,点击建议问题时,会发送该问题
   */
  prompts?: Array<PromptData<ChatType>>;
}

/**
 * 服务连接配置
 */
export interface ServerOptions {
  /**
   * 服务类型,目前仅支持api类型
   * - model 直接连接模型的api
   * - api 连接后端服务的api
   */
  type: 'model' | 'api';
  /**
   * api配置
   */
  api?: {
    /** api基础url */
    url: string;
    /** 动态获取token的方法 */
    token?: () => string;
    /** type为api时,tokenKey为请求头中token的key */
    tokenKey?: string;
  };
}

3. 核心 API 方法

import { qchat } from 'qchatController';

/**
 * 显式挂载
 * 组件初始化与DOM挂载完全解耦,提升组件使用灵活性,符合渐进式挂载的最佳实践
 */
qchant.mount(containerId, btnId);

// 设置智能指令
qchat.getInstance().setDirective({
  chatType: 'expRecommend',
  elements: [
    {
      type: 'text',
      value: `请帮我推荐一些符合教学要求的实践案例\n实践主题:`,
    },
    {
      type: 'input',
      placeholder: '请输入需要推荐的要求',
    },
  ],
});

// 提交用户输入
qchat.getInstance().submitInput({
  type: 'homeworkQa',
  query: '如何计算矩阵特征值?',
});

// 开启新对话
qchat.getInstance().startNewConversation();

// 更新配置
qchat.getInstance().updateOption({
  ui: { title: '数学助手' },
  enableHistory: false,
});

// 快速切换为对应场景的配置项
qchat.getInstance().setOptionsFromKey('lecture', {
  /* 这里可附加额外配置项 */
});

4. 事件交互系统

4.1 事件监听示例

import { qchat } from 'qchatController';
// 监听容器尺寸变化
qchat.eventBus.on('resize', ({ width, height }) => {
  console.log(`容器尺寸更新:${width}x${height}`);
});

// 监听配置选项变更
qchat.eventBus.on('optionChanged', (data) => {
  console.log('qchat选项有变更');
});

4.2 事件类型表

事件名称触发时机数据格式
toggleActive展开/收起qchat对话面板{ active: boolean }
updateOption触发更新配置项Partial<QChatOption<SceneType, ChatType>>
optionChanged配置项变更后触发QChatOption<SceneType, ChatType>
showToast触发toast提示{ message: string; type: 'success'|'error' }
newConversation开启新对话void
setDirective指令设置完成DirectiveData
submitInput用户提交输入InputSubmitType
resize容器尺寸变化{ width: number, height: number }
onExpImport业务端在实验案例采纳成功后触发,qchat监听到该事件后更新状态void
clickExpApply点击“申请试用”按钮触发,业务端监听该事件处理后续逻辑ExpRecommendItem
clickExpImport点击“采纳”按钮触发,业务端监听该事件处理后续逻辑ExpRecommendItem
clickFUT点击欢迎页的常用工具项目触发该事件,业务端监听到该事件后进行后续处理FUTItem
clickPromptLink点击输入框上方的快捷按钮,当快捷按钮的PromptData.isLink === true时,触发该事件,业务端监听该事件后进行后续处理PromptData
2.2.7

4 months ago

2.2.6

4 months ago

2.2.5

4 months ago

2.2.4

4 months ago

2.2.3

4 months ago

2.2.2

4 months ago

2.2.1

4 months ago

2.2.0

4 months ago

2.1.9

4 months ago

2.1.8

5 months ago

2.1.7

5 months ago

2.1.6

5 months ago

2.1.5

5 months ago

2.1.4

5 months ago

2.1.3

5 months ago

2.1.2

5 months ago

2.1.1

5 months ago

2.1.0

5 months ago

2.0.5

5 months ago

2.0.4

5 months ago

2.0.3

5 months ago

2.0.2

5 months ago

2.0.1

5 months ago

2.0.0

5 months ago