619 lines
16 KiB
Markdown
619 lines
16 KiB
Markdown
# AI Helper 表单集成文档
|
||
|
||
## 概述
|
||
|
||
AI Helper 是一个可全局集成的 AI 对话组件,支持两种展示模式:
|
||
|
||
- **图标模式(icon)**:悬浮图标 + 可拖拽弹框,默认展示在页面右下角
|
||
- **输入框模式(input)**:将对话输入框直接嵌入到页面指定位置,无弹框、无关闭按钮
|
||
|
||
两种模式均支持文本输入、图片上传、视频上传,输入框会根据内容自动调整高度。
|
||
|
||
---
|
||
|
||
## 快速开始
|
||
|
||
### 1. 引入组件
|
||
|
||
```vue
|
||
<template>
|
||
<div>
|
||
<!-- 你的页面内容 -->
|
||
|
||
<!-- 在页面底部引入 AI Helper -->
|
||
<ai-helper :agent_id="agentId" />
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
|
||
export default {
|
||
components: { AiHelper },
|
||
data() {
|
||
return {
|
||
agentId: '1' // Agent ID
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
---
|
||
|
||
## Props 参数
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| agent_id | String/Number | 是 | - | Agent 配置 ID,用于加载对应的 Agent 配置 |
|
||
| user_prompt | String | 否 | '' | 用户提示词,提供上下文数据,调用大模型时作为额外上下文传递 |
|
||
| display | String | 否 | 'icon' | 展示模式:`icon`(悬浮图标+弹框)/ `input`(嵌入式输入框) |
|
||
| input_title | String | 否 | '' | 输入框标题,显示在输入框上方,用于说明输入内容的用途 |
|
||
| default_input | String | 否 | '' | 默认的用户输入文案,组件初始化时自动填充到输入框中 |
|
||
|
||
---
|
||
|
||
## Events 事件
|
||
|
||
| 事件名 | 参数 | 说明 |
|
||
|--------|------|------|
|
||
| result | Object | 大模型返回结果时触发 |
|
||
|
||
### result 事件数据结构
|
||
|
||
```javascript
|
||
{
|
||
content: '返回的文本内容', // String - 原始返回内容
|
||
tokens: { // Object - Token 统计
|
||
total: 150,
|
||
prompt: 100,
|
||
completion: 50
|
||
},
|
||
contentObject: {}, // Object - JSON 格式返回内容(仅 outputType 为 json 时)
|
||
agentId: '1', // String/Number - 当前 Agent ID
|
||
timestamp: '2026-06-26T17:00:00.000Z' // String - 时间戳
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 展示模式说明
|
||
|
||
### 模式 1:图标模式(display="icon")
|
||
|
||
默认模式。页面右下角显示一个悬浮图标,点击后弹出可拖拽的对话弹框。
|
||
|
||
- 悬浮图标可拖拽移动
|
||
- 弹框可拖拽移动,带标题栏和关闭按钮
|
||
- 弹框内包含统一输入框(文本 + 上传)
|
||
|
||
```vue
|
||
<!-- 默认就是 icon 模式,无需显式指定 -->
|
||
<ai-helper agent_id="1" />
|
||
<!-- 等价于 -->
|
||
<ai-helper agent_id="1" display="icon" />
|
||
```
|
||
|
||
### 模式 2:输入框模式(display="input")
|
||
|
||
将对话输入框直接嵌入到页面中组件放置的位置,没有悬浮图标、没有弹框、没有关闭按钮。
|
||
|
||
- 组件挂载后自动加载 Agent 信息(无需点击)
|
||
- 统一输入框直接显示在页面中
|
||
- 文本输入区域根据内容自动增高(最小 3 行,最大 200px 后滚动)
|
||
- 支持图片/视频上传图标(根据 Agent 配置自动显示)
|
||
|
||
```vue
|
||
<ai-helper agent_id="1" display="input" />
|
||
```
|
||
|
||
### 统一输入框结构
|
||
|
||
两种模式共用同一个输入框设计,将文本输入、图片上传、视频上传整合为一个区域:
|
||
|
||
```
|
||
┌─────────────────────────────────┐
|
||
│ [已上传的图片/视频预览] │
|
||
│ │
|
||
│ 请输入内容... │
|
||
│ │
|
||
│ 📷 🎬 [发送] │
|
||
└─────────────────────────────────┘
|
||
```
|
||
|
||
- 文本区域:自动高度,最小 3 行(66px),最大 200px 后出现滚动条
|
||
- 左下角:图片上传 📷 和视频上传 🎬 图标按钮(根据 Agent 配置显示)
|
||
- 右下角:发送按钮
|
||
- 已上传文件在输入框顶部以缩略图形式预览,支持点击删除
|
||
|
||
---
|
||
|
||
## 基础集成示例
|
||
|
||
### 示例 1:最简集成(图标模式)
|
||
|
||
```vue
|
||
<template>
|
||
<page-box>
|
||
<div>你的页面内容</div>
|
||
<ai-helper agent_id="1" />
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox }
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 示例 2:监听返回结果
|
||
|
||
```vue
|
||
<template>
|
||
<page-box>
|
||
<div>你的页面内容</div>
|
||
|
||
<!-- 监听 result 事件 -->
|
||
<ai-helper
|
||
agent_id="1"
|
||
@result="onAiResult"
|
||
/>
|
||
|
||
<!-- 展示结果 -->
|
||
<div v-if="aiResult">
|
||
<h3>AI 分析结果</h3>
|
||
<p>{{ aiResult.content }}</p>
|
||
</div>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox },
|
||
data() {
|
||
return {
|
||
aiResult: null
|
||
}
|
||
},
|
||
methods: {
|
||
onAiResult(data) {
|
||
this.aiResult = data
|
||
console.log('AI 返回:', data.content)
|
||
console.log('Token 统计:', data.tokens)
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 示例 3:传递上下文数据
|
||
|
||
```vue
|
||
<template>
|
||
<page-box>
|
||
<!-- 表单内容 -->
|
||
<el-form :model="form">
|
||
<el-form-item label="姓名">
|
||
<el-input v-model="form.name" />
|
||
</el-form-item>
|
||
<el-form-item label="电话">
|
||
<el-input v-model="form.phone" />
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 传递表单数据作为上下文 -->
|
||
<ai-helper
|
||
agent_id="1"
|
||
:user_prompt="contextData"
|
||
@result="onAiResult"
|
||
/>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox },
|
||
data() {
|
||
return {
|
||
form: {
|
||
name: '',
|
||
phone: ''
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
// 将表单数据转为上下文字符串
|
||
contextData() {
|
||
return `当前表单数据:
|
||
姓名:${this.form.name}
|
||
电话:${this.form.phone}`
|
||
}
|
||
},
|
||
methods: {
|
||
onAiResult(data) {
|
||
// 处理 AI 返回结果
|
||
if (data.contentObject) {
|
||
// JSON 格式结果
|
||
console.log('JSON 结果:', data.contentObject)
|
||
} else {
|
||
// 文本格式结果
|
||
console.log('文本结果:', data.content)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 示例 4:输入框模式嵌入表单
|
||
|
||
将 AI 输入框直接嵌入到表单页面中,作为页面的一部分,而非悬浮弹框:
|
||
|
||
```vue
|
||
<template>
|
||
<page-box title="智能分析">
|
||
<!-- 表单内容 -->
|
||
<el-form :model="form" label-width="100px">
|
||
<el-form-item label="客户名称">
|
||
<el-input v-model="form.customerName" />
|
||
</el-form-item>
|
||
<el-form-item label="联系电话">
|
||
<el-input v-model="form.phone" />
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- AI 输入框直接嵌入页面 -->
|
||
<div style="margin-top: 20px;">
|
||
<ai-helper
|
||
agent_id="5"
|
||
display="input"
|
||
input_title="智能分析助手"
|
||
default_input="请帮我分析这个客户的基本信息"
|
||
:user_prompt="aiContext"
|
||
@result="handleAiResult"
|
||
/>
|
||
</div>
|
||
|
||
<!-- AI 结果展示 -->
|
||
<el-card v-if="aiResult" style="margin-top: 20px">
|
||
<div slot="header">AI 分析结果</div>
|
||
<pre>{{ aiResult.content }}</pre>
|
||
</el-card>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox },
|
||
data() {
|
||
return {
|
||
form: {
|
||
customerName: '',
|
||
phone: ''
|
||
},
|
||
aiResult: null
|
||
}
|
||
},
|
||
computed: {
|
||
aiContext() {
|
||
return `请根据以下客户信息进行分析:
|
||
客户名称:${this.form.customerName}
|
||
联系电话:${this.form.phone}`
|
||
}
|
||
},
|
||
methods: {
|
||
handleAiResult(data) {
|
||
this.aiResult = data
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 示例 5:表单场景完整集成(图标模式)
|
||
|
||
```vue
|
||
<template>
|
||
<page-box title="客户信息录入">
|
||
<el-form :model="form" label-width="100px">
|
||
<el-form-item label="客户名称">
|
||
<el-input v-model="form.customerName" />
|
||
</el-form-item>
|
||
<el-form-item label="联系电话">
|
||
<el-input v-model="form.phone" />
|
||
</el-form-item>
|
||
<el-form-item label="地址">
|
||
<el-input v-model="form.address" type="textarea" />
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- AI Helper 集成 -->
|
||
<ai-helper
|
||
agent_id="5"
|
||
:user_prompt="aiContext"
|
||
@result="handleAiResult"
|
||
/>
|
||
|
||
<!-- AI 结果展示区域 -->
|
||
<el-card v-if="aiResult" style="margin-top: 20px">
|
||
<div slot="header">AI 分析结果</div>
|
||
<div v-if="aiResult.contentObject">
|
||
<p>建议标签:{{ aiResult.contentObject.tags }}</p>
|
||
<p>建议分类:{{ aiResult.contentObject.category }}</p>
|
||
</div>
|
||
<div v-else>
|
||
<pre>{{ aiResult.content }}</pre>
|
||
</div>
|
||
</el-card>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox },
|
||
data() {
|
||
return {
|
||
form: {
|
||
customerName: '',
|
||
phone: '',
|
||
address: ''
|
||
},
|
||
aiResult: null
|
||
}
|
||
},
|
||
computed: {
|
||
aiContext() {
|
||
return `请根据以下客户信息进行分析:
|
||
客户名称:${this.form.customerName}
|
||
联系电话:${this.form.phone}
|
||
地址:${this.form.address}
|
||
|
||
请以 JSON 格式返回分析结果,包含 tags(标签数组)和 category(分类)。`
|
||
}
|
||
},
|
||
methods: {
|
||
handleAiResult(data) {
|
||
this.aiResult = data
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 示例 6:使用输入框标题和默认文案
|
||
|
||
在 input 模式下,可以使用 `input_title` 和 `default_input` 参数来优化用户体验:
|
||
|
||
```vue
|
||
<template>
|
||
<page-box title="施肥方案管理">
|
||
<el-form :model="form" label-width="100px">
|
||
<el-form-item label="作物">
|
||
<el-select v-model="form.cropId" placeholder="请选择作物">
|
||
<el-option v-for="crop in cropList" :key="crop.id" :label="crop.name" :value="crop.id" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="物候期">
|
||
<el-select v-model="form.phenologyId" placeholder="请选择物候期">
|
||
<el-option v-for="p in phenologyList" :key="p.id" :label="p.name" :value="p.id" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- AI 输入框带标题和默认文案 -->
|
||
<div style="margin-top: 20px;">
|
||
<ai-helper
|
||
agent_id="4"
|
||
display="input"
|
||
input_title="智能施肥方案生成"
|
||
default_input="请根据选择的作物和物候期,制定科学的施肥方案"
|
||
:user_prompt="aiContext"
|
||
@result="handleAiResult"
|
||
/>
|
||
</div>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
import AiHelper from '@/components/ai/ai_helper.vue'
|
||
import PageBox from '@/components/pageBox.vue'
|
||
|
||
export default {
|
||
components: { AiHelper, PageBox },
|
||
data() {
|
||
return {
|
||
form: {
|
||
cropId: null,
|
||
phenologyId: null
|
||
},
|
||
cropList: [],
|
||
phenologyList: []
|
||
}
|
||
},
|
||
computed: {
|
||
aiContext() {
|
||
const crop = this.cropList.find(c => c.id === this.form.cropId)
|
||
const phenology = this.phenologyList.find(p => p.id === this.form.phenologyId)
|
||
return `当前选择的作物:${crop ? crop.name : '未选择'}
|
||
当前物候期:${phenology ? phenology.name : '未选择'}
|
||
|
||
请根据以上信息制定施肥方案,返回 JSON 格式:
|
||
{
|
||
"formulaName": "配方名称",
|
||
"applyType": "施肥方式",
|
||
"totalAmount": 总用量,
|
||
"details": [...]
|
||
}`
|
||
}
|
||
},
|
||
methods: {
|
||
handleAiResult(data) {
|
||
if (data.contentObject) {
|
||
// 回填表单
|
||
console.log('AI 返回的施肥方案:', data.contentObject)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
**参数说明:**
|
||
- `input_title="智能施肥方案生成"`:在输入框上方显示标题,帮助用户理解该输入框的用途
|
||
- `default_input="请根据选择的作物和物候期,制定科学的施肥方案"`:组件初始化时自动填充到输入框,用户可以在此基础上修改或直接发送
|
||
|
||
---
|
||
|
||
## 组件功能说明
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 悬浮图标 | icon 模式下显示在页面右下角,可拖拽移动 |
|
||
| 对话弹框 | icon 模式下点击图标打开,可拖拽移动,无遮罩层 |
|
||
| 嵌入式输入框 | input 模式下直接嵌入页面,无弹框无关闭按钮 |
|
||
| 统一输入框 | 文本输入 + 图片上传 + 视频上传整合为一个输入区域 |
|
||
| 自动高度 | 文本输入区域根据内容自动增高,最小 3 行,最大 200px |
|
||
| 图片上传 | 根据 Agent 配置 `supportImage` 自动显示上传图标 |
|
||
| 视频上传 | 根据 Agent 配置 `supportVideo` 自动显示上传图标 |
|
||
| 文件预览 | 已上传的图片/视频在输入框顶部以缩略图预览,支持删除 |
|
||
| 结果输出 | 调用成功后通过 `@result` 事件抛出 |
|
||
|
||
---
|
||
|
||
## 表单快速填充场景
|
||
|
||
### 场景说明
|
||
|
||
在业务系统中,很多表单需要用户手动填写大量字段。通过集成 AI Helper(Agent ID = 4),可以实现表单快速填充:
|
||
|
||
1. 用户通过 AI 对话描述需求(如"帮我填一个客户信息,张三,电话 13800138000")
|
||
2. AI 分析用户输入,返回 JSON 格式的表单数据
|
||
3. 前端监听 `@result` 事件,将返回的 JSON 数据自动回填到表单中
|
||
|
||
### 接入步骤
|
||
|
||
#### 步骤 1:整理表单字段信息
|
||
|
||
整理目标表单的所有字段,包含以下信息:
|
||
|
||
| 属性名 | 类型 | 含义 |
|
||
|--------|------|------|
|
||
| 字段名 | 数据类型 | 字段说明 |
|
||
|
||
例如:
|
||
| 属性名 | 类型 | 含义 |
|
||
|--------|------|------|
|
||
| plateNumber | String | 车牌号 |
|
||
| vehicleType | String | 车型 |
|
||
| driverId | Long | 司机ID |
|
||
|
||
#### 步骤 2:构建 user_prompt
|
||
|
||
将字段信息告诉 AI,让它知道需要返回什么格式:
|
||
|
||
```javascript
|
||
computed: {
|
||
aiPrompt() {
|
||
return `请根据用户描述填充表单,返回 JSON 格式:
|
||
{
|
||
"plateNumber": "车牌号",
|
||
"vehicleType": "车型",
|
||
"driverId": 司机ID
|
||
}
|
||
只返回 JSON,不要其他内容。`
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 步骤 3:集成组件并处理回调
|
||
|
||
```vue
|
||
<template>
|
||
<page-box>
|
||
<el-form :model="form">
|
||
<!-- 你的表单字段 -->
|
||
</el-form>
|
||
|
||
<ai-helper
|
||
agent_id="4"
|
||
:user_prompt="aiPrompt"
|
||
@result="handleAiResult"
|
||
/>
|
||
</page-box>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
computed: {
|
||
aiPrompt() {
|
||
return `根据用户描述填充表单,返回 JSON:
|
||
{
|
||
"plateNumber": "车牌号",
|
||
"vehicleType": "车型",
|
||
"driverId": 司机ID
|
||
}
|
||
只返回 JSON。`
|
||
}
|
||
},
|
||
methods: {
|
||
handleAiResult(data) {
|
||
if (data.contentObject) {
|
||
// 回填表单
|
||
Object.keys(data.contentObject).forEach(key => {
|
||
if (this.form.hasOwnProperty(key)) {
|
||
this.$set(this.form, key, data.contentObject[key])
|
||
}
|
||
})
|
||
this.$message.success('已填充')
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 关键点
|
||
|
||
1. **Agent ID = 4**:表单快速填充固定使用
|
||
2. **字段说明要清晰**:告诉 AI 字段名、类型、含义
|
||
3. **返回 JSON 格式**:Agent 的 outputType 必须配置为 json
|
||
4. **自动回填**:根据返回的 JSON key 匹配表单字段名
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **Agent ID 必须有效**:确保传入的 `agent_id` 在后端 `llm_agent_config` 表中存在且状态为启用
|
||
2. **user_prompt 为可选**:不传则仅使用 Agent 配置的系统提示词和用户提示词模板
|
||
3. **结果格式**:根据 Agent 的 `outputType` 配置,`contentObject` 仅在 `outputType=json` 时有值
|
||
4. **组件位置**:
|
||
- icon 模式:建议放在页面模板的最外层或 `page-box` 内部,确保悬浮层级正确
|
||
- input 模式:放在表单或内容区域中需要嵌入输入框的位置即可
|
||
5. **Token 统计**:每次调用会返回 Token 消耗统计,可用于成本监控
|
||
6. **display 模式选择**:
|
||
- icon 模式适合全局辅助工具,用户按需打开
|
||
- input 模式适合 AI 驱动的业务页面,输入框作为页面核心功能的一部分
|
||
|
||
---
|
||
|
||
## 前置条件
|
||
|
||
- 需要在后台 Agent 管理中配置好对应的 Agent(系统提示词、模型等)
|
||
- 确保 `/static/ai_helper.png` 和 `/static/ai_helper_bai.png` 图标文件存在
|