feat(HomePage): 优化信息展示为两列网格布局并新增标签格式化功能

This commit is contained in:
2026-04-01 14:36:23 +08:00
parent 548b7084a6
commit 9a5d1cc888

View File

@@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import * as ww from '@wecom/jssdk' import * as ww from '@wecom/jssdk'
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -27,6 +26,11 @@ interface RawAnswerItem {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// 0. 数据转换函数 // 0. 数据转换函数
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// 格式化标签:去掉末尾的冒号和空格,使显示更紧凑
function formatLabel(topic: string): string {
return topic.replace(/[:]\s*$/, '').trim()
}
function mapAnswersToCustomerInfo(answers: RawAnswerItem[]): CustomerInfo { function mapAnswersToCustomerInfo(answers: RawAnswerItem[]): CustomerInfo {
const mainFieldsMap: { [key: string]: keyof CustomerInfo } = { const mainFieldsMap: { [key: string]: keyof CustomerInfo } = {
'您的姓名:': 'name', '您的姓名:': 'name',
@@ -53,7 +57,6 @@ function mapAnswersToCustomerInfo(answers: RawAnswerItem[]): CustomerInfo {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// 1. 响应式状态 // 1. 响应式状态
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const router = useRouter()
const isWWReady = ref(false) const isWWReady = ref(false)
const errorMessage = ref<string | null>(null) const errorMessage = ref<string | null>(null)
const isLoading = ref(false) // 按钮提交 loading const isLoading = ref(false) // 按钮提交 loading
@@ -62,7 +65,6 @@ const isPageLoading = ref(true) // 页面初始化/切换客户时的全局
// 初始值全部设为 null不信任任何本地缓存 // 初始值全部设为 null不信任任何本地缓存
const externalUserId = ref<string | null>(null) const externalUserId = ref<string | null>(null)
const customerInfo = ref<CustomerInfo | null>(null) const customerInfo = ref<CustomerInfo | null>(null)
const secondStageInfo = ref<CustomerInfo | null>(null)
const showPhoneInput = ref(false) const showPhoneInput = ref(false)
const phoneNumber = ref('') const phoneNumber = ref('')
@@ -118,7 +120,6 @@ const fetchAndCheckExternalContact = async () => {
isPageLoading.value = true isPageLoading.value = true
externalUserId.value = null externalUserId.value = null
customerInfo.value = null customerInfo.value = null
secondStageInfo.value = null
errorMessage.value = null errorMessage.value = null
try { try {
@@ -156,19 +157,9 @@ const fetchAndCheckExternalContact = async () => {
const raw1 = result.data.form_content[0].answers as RawAnswerItem[] const raw1 = result.data.form_content[0].answers as RawAnswerItem[]
customerInfo.value = mapAnswersToCustomerInfo(raw1) customerInfo.value = mapAnswersToCustomerInfo(raw1)
localStorage.setItem('customer_info', JSON.stringify(customerInfo.value)) localStorage.setItem('customer_info', JSON.stringify(customerInfo.value))
// 解析二阶
if (result.data.form_content.length > 1) {
const raw2 = result.data.form_content[1].answers as RawAnswerItem[]
secondStageInfo.value = mapAnswersToCustomerInfo(raw2)
localStorage.setItem('second_stage_info', JSON.stringify(secondStageInfo.value))
} else {
localStorage.removeItem('second_stage_info')
}
} else { } else {
// 无表单记录,清空缓存 // 无表单记录,清空缓存
localStorage.removeItem('customer_info') localStorage.removeItem('customer_info')
localStorage.removeItem('second_stage_info')
} }
} catch (error: any) { } catch (error: any) {
console.error('获取客户信息流程失败:', error) console.error('获取客户信息流程失败:', error)
@@ -251,32 +242,19 @@ onMounted(async () => {
<!-- 场景 A已获取到评估信息 --> <!-- 场景 A已获取到评估信息 -->
<div v-if="customerInfo" class="customer-details-card fade-in"> <div v-if="customerInfo" class="customer-details-card fade-in">
<h2><span class="card-icon green">📋</span> 客户评估信息</h2> <h2><span class="card-icon green">📋</span> 客户评估信息</h2>
<div class="qa-section">
<ul>
<li v-for="(item, index) in customerInfo.additional_info" :key="index" class="qa-item">
<span class="question">{{ index + 1 }}. {{ item.topic }} :</span>
<span class="answer">{{ item.answer }}</span>
</li>
</ul>
</div>
<!-- 二阶展示 --> <!-- 紧凑信息展示区使用两列网格布局 -->
<div v-if="secondStageInfo" class="second-stage-section"> <div class="info-grid">
<h2 class="divider-title"><span class="card-icon green">📋</span> 二阶评估信息</h2> <div class="info-card" v-for="(item, index) in customerInfo.additional_info" :key="index">
<div class="qa-section"> <span class="info-label">{{ formatLabel(item.topic) }}</span>
<ul> <span class="info-value">{{ item.answer }}</span>
<li v-for="(item, index) in secondStageInfo.additional_info" :key="index" class="qa-item qa-item-stacked">
<span class="question">{{ index + 1 }}. {{ item.topic }} :</span>
<span class="answer">{{ item.answer }}</span>
</li>
</ul>
</div> </div>
</div> </div>
<div class="card-meta"> <div class="card-meta">
<div class="button-group"> <div class="button-group">
<button v-if="!secondStageInfo" class="card-button" @click="sendFormLink" :disabled="isLoading"> <button class="card-button" @click="sendFormLink" :disabled="isLoading">
{{ isLoading ? '发送中...' : '📧 发送二阶评估表' }} {{ isLoading ? '发送中...' : '📧 发送评估表' }}
</button> </button>
</div> </div>
</div> </div>
@@ -393,53 +371,34 @@ onMounted(async () => {
font-size: 16px; font-size: 16px;
} }
/* 4. QA 问答列表项 */ /* 紧凑信息网格布局:两列展示 */
.qa-section ul { .info-grid {
list-style: none; display: grid;
padding: 0; grid-template-columns: repeat(2, 1fr);
margin: 0; gap: 8px;
} }
.qa-item { .info-card {
margin-bottom: 12px; background: #f8fafc;
padding-bottom: 12px; border-radius: 8px;
border-bottom: 1px solid #f0f2f5; padding: 10px 12px;
display: flex; display: flex;
flex-direction: column; /* 侧边栏窄,垂直排列体验更好 */ flex-direction: column;
gap: 4px; gap: 4px;
} }
.qa-item:last-child { .info-label {
border-bottom: none; font-size: 11px;
color: #718096;
font-weight: 500;
} }
.question { .info-value {
font-weight: 600;
color: #4a5568;
font-size: 13px;
line-height: 1.4;
}
.answer {
color: #2d3748;
font-size: 14px; font-size: 14px;
line-height: 1.5; color: #2d3748;
background: #f8fafc; font-weight: 600;
padding: 8px 12px;
border-radius: 6px;
word-break: break-all; word-break: break-all;
} }
/* 二阶特殊样式 */
.divider-title {
margin-top: 24px;
padding-top: 16px;
border-top: 2px dashed #edf2f7;
font-size: 15px;
color: #2d3748;
}
/* 5. 按钮组与按钮 */
.card-meta { .card-meta {
margin-top: 20px; margin-top: 20px;
} }