8.7 KiB
8.7 KiB
保险智能客服系统 — 前端开发文档
文档版本:V1.0 更新日期:2026-06-25 技术栈:Vue 3 + TypeScript + Element Plus + Vite
一、项目结构
frontend/
├── src/
│ ├── assets/ # 静态资源
│ ├── components/ # 公共组件
│ │ ├── ChatEmbed.vue # BaoDan 对话 iframe
│ │ ├── ChatFilters.vue # 险种/保司筛选器
│ │ ├── ChatCopyButton.vue # 复制按钮
│ │ ├── RecommendForm.vue # 推荐表单
│ │ └── RecommendResult.vue # 推荐结果
│ ├── composables/ # 组合式函数
│ │ ├── useAuth.ts # 认证逻辑
│ │ └── useDraft.ts # 草稿保存
│ ├── constants/ # 常量定义
│ │ └── index.ts # 访客页面白名单等
│ ├── pages/ # 页面视图
│ │ ├── admin/ # 管理后台页面
│ │ ├── ChatPage.vue # 对话页面
│ │ ├── LoginPage.vue # 登录页面
│ │ ├── RecommendPage.vue # 推荐页面
│ │ └── RecommendHistory.vue # 历史方案
│ ├── router/ # 路由配置
│ │ └── index.ts
│ ├── types/ # TypeScript 类型
│ │ └── index.ts
│ ├── utils/ # 工具函数
│ │ └── api.ts # axios 封装
│ ├── App.vue # 主布局
│ └── main.ts # 入口文件
├── package.json
└── vite.config.ts
二、待开发功能
2.1 产品推荐联调
目标:联调 RecommendPage 与后端 API
修改文件:src/pages/RecommendPage.vue
当前代码:
async function onSubmit(formData: RecommendRequest) {
loading.value = true
try {
const submitRes = await api.post('/recommend/generate', formData)
const taskId = submitRes.data.task_id
// ... 轮询逻辑
} catch {
// 错误已由 api 拦截器处理
}
}
需要修改:
- 确认后端返回格式
- 适配轮询逻辑
- 处理超时情况
2.2 推荐结果适配
目标:适配后端返回的方案格式
修改文件:src/components/RecommendResult.vue
后端返回格式:
{
"status": "done",
"proposal": {
"customer_name": "张三",
"plans": [
{
"name": "基础方案",
"total_premium": 12000,
"items": [
{
"product_name": "XX重疾险",
"coverage_amount": 300000,
"annual_premium": 8000,
"recommend_reason": "性价比高"
}
],
"summary": "适合预算有限的客户"
}
],
"disclaimer": "以上方案仅供参考"
}
}
需要修改:
- 适配 plans 数组结构
- 渲染产品表格
- 显示总保费
2.3 用户批量导入
目标:添加 Excel 批量导入功能
修改文件:src/pages/admin/UsersPage.vue
添加内容:
<!-- 导入按钮 -->
<el-upload
:action="'/insurance/admin/users/batch-import'"
:headers="uploadHeaders"
:on-success="onImportSuccess"
:on-error="onImportError"
accept=".xlsx,.xls"
:show-file-list="false"
>
<el-button>批量导入</el-button>
</el-upload>
添加逻辑:
const uploadHeaders = {
Authorization: `Bearer ${localStorage.getItem('token')}`
}
function onImportSuccess(response: any) {
if (response.code === 0) {
ElMessage.success('导入成功')
loadData()
} else {
ElMessage.error(response.message || '导入失败')
}
}
function onImportError() {
ElMessage.error('导入失败')
}
三、类型定义
3.1 推荐相关类型
文件:src/types/index.ts
/** 推荐请求参数 */
export interface RecommendRequest {
customer_name: string
customer_age: number
customer_gender: 'male' | 'female'
health_status: '健康' | '有既往病史' | '慢性病' | '重大疾病史'
occupation: string
annual_income: number
monthly_budget: number
insurance_types: string[]
coverage_amount: number
coverage_period: string
existing_policies?: ExistingPolicy[]
}
/** 已有保单 */
export interface ExistingPolicy {
product_name: string
insurance_type: string
coverage_amount: number
annual_premium: number
}
/** 推荐方案 */
export interface RecommendProposal {
customer_name: string
plans: InsurancePlan[]
disclaimer: string
}
/** 保险方案 */
export interface InsurancePlan {
name: string
total_premium: number
items: InsuranceItem[]
summary: string
}
/** 保险产品 */
export interface InsuranceItem {
product_name: string
coverage_amount: number
annual_premium: number
recommend_reason: string
}
/** 推荐记录 */
export interface RecommendRecord {
id: string
customer_name: string
insurance_types: string[]
status: 'pending' | 'processing' | 'done' | 'failed'
created_at: string
completed_at?: string
}
四、API 调用规范
4.1 请求格式
import api from '@/utils/api'
// GET 请求
const res = await api.get('/admin/users', { params: { page: 1 } })
// POST 请求
const res = await api.post('/recommend/generate', formData)
// PUT 请求
const res = await api.put(`/admin/users/${id}`, userData)
// DELETE 请求
const res = await api.delete(`/admin/users/${id}`)
4.2 响应处理
// axios 拦截器已处理 code !== 0 的情况
// 这里只需要处理成功情况
try {
const res = await api.get('/admin/users')
// res.data = { items: [...], total: 100 }
users.value = res.data?.items || []
} catch (error) {
// 错误已由拦截器显示 ElMessage
}
4.3 访客页面
import { isGuestPage } from '@/constants'
// 访客页面不发送 token
if (!isGuestPage(window.location.pathname)) {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
}
五、组件开发规范
5.1 页面组件
<template>
<div class="page-container">
<!-- 页面内容 -->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import api from '@/utils/api'
// 响应式数据
const loading = ref(false)
const data = ref<any[]>([])
// 加载数据
async function loadData() {
loading.value = true
try {
const res = await api.get('/admin/users')
data.value = res.data?.items || []
} finally {
loading.value = false
}
}
// 页面加载时执行
onMounted(loadData)
</script>
<style scoped>
.page-container {
padding: 20px;
}
</style>
5.2 表单组件
<template>
<el-form :model="form" :rules="rules" ref="formRef">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form-item>
</el-form>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import api from '@/utils/api'
const formRef = ref()
const form = reactive({ username: '' })
const rules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }]
}
async function handleSubmit() {
await formRef.value?.validate()
try {
await api.post('/admin/users', form)
ElMessage.success('提交成功')
} catch {
// 错误已由拦截器处理
}
}
</script>
六、样式规范
6.1 页面容器
.page-container {
padding: 20px;
height: 100%;
overflow: auto;
box-sizing: border-box;
}
6.2 卡片样式
.page-card {
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
6.3 表格样式
:deep(.el-table th) {
background: #fafafa !important;
color: #606266;
font-weight: 600;
}
七、测试清单
| # | 页面 | 测试项 | 验证标准 |
|---|---|---|---|
| 1 | LoginPage | 账密登录 | 输入正确账密 → 跳转 /chat |
| 2 | LoginPage | 表单校验 | 空表单提交 → 显示错误提示 |
| 3 | ChatPage | 对话功能 | 发送消息 → 收到 AI 回答 |
| 4 | ChatPage | 险种筛选 | 切换险种 → 对话正常 |
| 5 | RecommendPage | 生成方案 | 填写表单 → 显示 3 套方案 |
| 6 | RecommendPage | 导出 | 点击导出 → 下载文件 |
| 7 | UsersPage | 用户列表 | 显示用户数据 |
| 8 | UsersPage | 新增用户 | 填写表单 → 用户增加 |
| 9 | UsersPage | 批量导入 | 上传 Excel → 用户增加 |
| 10 | StatsPage | 统计数据 | 显示图表和数据 |