baodan/docs/前端开发文档.md

8.7 KiB
Raw Blame History

保险智能客服系统 — 前端开发文档

文档版本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 拦截器处理
  }
}

需要修改

  1. 确认后端返回格式
  2. 适配轮询逻辑
  3. 处理超时情况

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": "以上方案仅供参考"
  }
}

需要修改

  1. 适配 plans 数组结构
  2. 渲染产品表格
  3. 显示总保费

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 统计数据 显示图表和数据