feat(表单信息展示): 支持多表单数据展示和筛选功能
- 重构表单数据解析逻辑,支持从数组格式中提取多表单数据 - 添加表单筛选按钮,可按表单标题筛选显示内容 - 优化数据结构处理,支持问答列表和旧格式的兼容 - 改进UI布局,添加表单标题和分割线提升可读性
This commit is contained in:
@@ -14,12 +14,26 @@
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="card-title">表单信息</h3>
|
||||
<div class="form-filter">
|
||||
<button
|
||||
v-for="option in formFilterOptions"
|
||||
:key="option"
|
||||
class="form-filter-btn"
|
||||
:class="{ active: formFilter === option }"
|
||||
@click="formFilter = option"
|
||||
>
|
||||
{{ option }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="form-data-list">
|
||||
<div v-for="(field, index) in formFields" :key="index" class="form-field">
|
||||
<span class="field-label">{{ field.label }}:</span>
|
||||
<span class="field-value">{{ field.value }}</span>
|
||||
<div v-for="(section, sectionIndex) in displayedFormSections" :key="sectionIndex" class="form-section">
|
||||
<div v-if="section.title" class="form-section-title">{{ section.title }}</div>
|
||||
<div class="form-data-list">
|
||||
<div v-for="(field, index) in section.fields" :key="index" class="form-field">
|
||||
<span class="field-label">{{ field.label }}:</span>
|
||||
<span class="field-value">{{ field.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -132,7 +146,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
// Props
|
||||
@@ -166,79 +180,107 @@ const chatMessages = computed(() => {
|
||||
return props.chatInfo?.messages || []
|
||||
})
|
||||
|
||||
// 表单字段数据 (已更新)
|
||||
const formFields = computed(() => {
|
||||
const formFilter = ref('全部')
|
||||
|
||||
const formSections = computed(() => {
|
||||
const formData = props.formInfo
|
||||
console.log(8888888,formData)
|
||||
// --- NEW LOGIC: 处理新的数组格式(问答列表) ---
|
||||
if (Array.isArray(formData) && formData.length > 0) {
|
||||
// 检查数组项结构,确保是新的问答格式
|
||||
if (formData[0].question_label && formData[0].answer) {
|
||||
// 直接将问答列表映射为 { label: question_label, value: answer } 格式
|
||||
return formData.map(item => ({
|
||||
label: item.question_label,
|
||||
value: item.answer || '暂无回答'
|
||||
const emptyFields = [
|
||||
{ label: '姓名', value: '暂无数据' },
|
||||
{ label: '联系方式', value: '暂无数据' },
|
||||
{ label: '孩子信息', value: '暂无数据' },
|
||||
{ label: '地区', value: '暂无数据' }
|
||||
]
|
||||
|
||||
const makeSection = (fields, title = '表单信息') => [{ title, fields }]
|
||||
|
||||
const buildFieldsFromAnswers = (answers = []) => {
|
||||
return answers.map(item => ({
|
||||
label: item.question_label,
|
||||
value: item.answer || '暂无回答'
|
||||
}))
|
||||
}
|
||||
|
||||
let dataArray = null
|
||||
if (Array.isArray(formData)) {
|
||||
dataArray = formData
|
||||
} else if (formData && Array.isArray(formData.data)) {
|
||||
dataArray = formData.data
|
||||
}
|
||||
|
||||
if (Array.isArray(dataArray) && dataArray.length > 0) {
|
||||
if (dataArray[0].form_title && Array.isArray(dataArray[0].answers)) {
|
||||
return dataArray.map(form => ({
|
||||
title: form.form_title || '表单信息',
|
||||
fields: buildFieldsFromAnswers(form.answers || [])
|
||||
}))
|
||||
}
|
||||
if (dataArray[0].question_label && Object.prototype.hasOwnProperty.call(dataArray[0], 'answer')) {
|
||||
return makeSection(buildFieldsFromAnswers(dataArray))
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------
|
||||
|
||||
// Fallback: 如果数据为空、null 或旧的空对象格式
|
||||
if (!formData || (typeof formData === 'object' && Object.keys(formData).length === 0)) {
|
||||
return [
|
||||
{ label: '姓名', value: '暂无数据' },
|
||||
{ label: '联系方式', value: '暂无数据' },
|
||||
{ label: '孩子信息', value: '暂无数据' },
|
||||
{ label: '地区', value: '暂无数据' }
|
||||
return makeSection(emptyFields)
|
||||
}
|
||||
|
||||
let fields = []
|
||||
if (formData.name || formData.mobile || formData.child_name) {
|
||||
const customerInfo = [formData.name, formData.mobile, formData.child_relation, formData.occupation].filter(item => item && item !== '暂无').join(' | ')
|
||||
const childInfo = [formData.child_name, formData.child_gender, formData.child_education].filter(item => item && item !== '暂无').join(' | ')
|
||||
|
||||
fields = [
|
||||
{ label: '客户信息', value: customerInfo || '暂无' },
|
||||
{ label: '孩子信息', value: childInfo || '暂无' },
|
||||
{ label: '地区', value: formData.territory || '暂无' }
|
||||
]
|
||||
|
||||
if (formData.additional_info && Array.isArray(formData.additional_info)) {
|
||||
formData.additional_info.forEach((item) => {
|
||||
fields.push({
|
||||
label: item.topic,
|
||||
value: item.answer
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const customerInfo = [formData.expandTwentyOne, formData.expandOne].filter(item => item && item !== '暂无').join(' | ')
|
||||
const childInfo = [formData.expandTwentyNine, formData.expandTwentyFive, formData.expandTwo].filter(item => item && item !== '暂无').join(' | ')
|
||||
|
||||
fields = [
|
||||
{ label: '客户信息', value: customerInfo || '暂无' },
|
||||
{ label: '孩子信息', value: childInfo || '暂无' },
|
||||
{ label: '学习状态', value: formData.expandFive || '暂无' },
|
||||
{ label: '沟通情况', value: formData.expandEight || '暂无' },
|
||||
{ label: '主要问题', value: formData.expandTwentySeven || '暂无' },
|
||||
{ label: '关注领域', value: formData.expandFifteen || '暂无' },
|
||||
{ label: '学习成绩', value: formData.expandFourteen || '暂无' },
|
||||
{ label: '孩子数量', value: formData.expandTwenty || '暂无' },
|
||||
{ label: '预期时间', value: formData.expandThirty || '暂无' }
|
||||
]
|
||||
}
|
||||
|
||||
// --- OLD LOGIC: 处理旧的对象格式(保持兼容性) ---
|
||||
let fields = []
|
||||
|
||||
// 检查是否为第一种格式(包含name, mobile等字段)
|
||||
if (formData.name || formData.mobile || formData.child_name) {
|
||||
const customerInfo = [formData.name, formData.mobile, formData.child_relation, formData.occupation].filter(item => item && item !== '暂无').join(' | ')
|
||||
const childInfo = [formData.child_name, formData.child_gender, formData.child_education].filter(item => item && item !== '暂无').join(' | ')
|
||||
|
||||
fields = [
|
||||
{ label: '客户信息', value: customerInfo || '暂无' },
|
||||
{ label: '孩子信息', value: childInfo || '暂无' },
|
||||
{ label: '地区', value: formData.territory || '暂无' }
|
||||
]
|
||||
|
||||
// 如果有additional_info,添加所有问题
|
||||
if (formData.additional_info && Array.isArray(formData.additional_info)) {
|
||||
formData.additional_info.forEach((item) => {
|
||||
fields.push({
|
||||
label: item.topic,
|
||||
value: item.answer
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// 第二种格式(expandXXX字段)
|
||||
const customerInfo = [formData.expandTwentyOne, formData.expandOne].filter(item => item && item !== '暂无').join(' | ')
|
||||
const childInfo = [formData.expandTwentyNine, formData.expandTwentyFive, formData.expandTwo].filter(item => item && item !== '暂无').join(' | ')
|
||||
|
||||
fields = [
|
||||
{ label: '客户信息', value: customerInfo || '暂无' },
|
||||
{ label: '孩子信息', value: childInfo || '暂无' },
|
||||
{ label: '学习状态', value: formData.expandFive || '暂无' },
|
||||
{ label: '沟通情况', value: formData.expandEight || '暂无' },
|
||||
{ label: '主要问题', value: formData.expandTwentySeven || '暂无' },
|
||||
{ label: '关注领域', value: formData.expandFifteen || '暂无' },
|
||||
{ label: '学习成绩', value: formData.expandFourteen || '暂无' },
|
||||
{ label: '孩子数量', value: formData.expandTwenty || '暂无' },
|
||||
{ label: '预期时间', value: formData.expandThirty || '暂无' }
|
||||
]
|
||||
}
|
||||
// 合并表单数据和聊天数据
|
||||
const allFields = [...fields]
|
||||
|
||||
return allFields
|
||||
return makeSection(fields)
|
||||
})
|
||||
|
||||
const formFilterOptions = computed(() => {
|
||||
const titles = formSections.value.map(section => section.title).filter(Boolean)
|
||||
const uniqueTitles = Array.from(new Set(titles))
|
||||
if (uniqueTitles.length <= 1) return ['全部']
|
||||
return ['全部', ...uniqueTitles]
|
||||
})
|
||||
|
||||
const displayedFormSections = computed(() => {
|
||||
if (formFilter.value === '全部') return formSections.value
|
||||
const filtered = formSections.value.filter(section => section.title === formFilter.value)
|
||||
return filtered.length > 0 ? filtered : formSections.value
|
||||
})
|
||||
|
||||
watch(formFilterOptions, (options) => {
|
||||
if (!options.includes(formFilter.value)) {
|
||||
formFilter.value = options[0] || '全部'
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
|
||||
// 聊天数据
|
||||
const chatData = computed(() => ({
|
||||
@@ -507,6 +549,58 @@ const formatDateTime = (dateTimeString) => {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-filter {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.form-filter-btn {
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #e5e7eb;
|
||||
background: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #6b7280;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.form-filter-btn.active {
|
||||
border-color: #10b981;
|
||||
color: #059669;
|
||||
background: #ecfdf5;
|
||||
}
|
||||
|
||||
.form-filter-btn:hover {
|
||||
color: #059669;
|
||||
border-color: #a7f3d0;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.form-section + .form-section {
|
||||
margin-top: 16px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px dashed #e5e7eb;
|
||||
}
|
||||
|
||||
.form-section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
background: #f0fdf4;
|
||||
border: 1px solid #dcfce7;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
// 表单字段样式
|
||||
.form-data-list {
|
||||
.form-field {
|
||||
@@ -884,4 +978,4 @@ const formatDateTime = (dateTimeString) => {
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -605,7 +605,7 @@ async function getCustomerForm() {
|
||||
const res = await getCustomerFormInfo(params)
|
||||
console.log('获取客户表单数据:', res)
|
||||
if(res.code === 200) {
|
||||
formInfo.value = res.data[0].answers || []
|
||||
formInfo.value = res.data || []
|
||||
}
|
||||
} catch (error) {
|
||||
// 静默处理错误
|
||||
|
||||
Reference in New Issue
Block a user