新增项目基础结构,包括Vue3、Pinia、Element Plus等核心依赖 添加路由配置和用户认证状态管理 实现销售数据看板、客户画像、团队管理等核心功能模块 集成图表库和API请求工具,完成基础样式配置
992 lines
22 KiB
Vue
992 lines
22 KiB
Vue
<template>
|
||
<div class="customer-detail-container">
|
||
<div v-if="selectedContact" class="customer-detail-content">
|
||
<!-- 头部信息 -->
|
||
<div class="customer-header">
|
||
<h3>{{ selectedContact.name }}</h3>
|
||
<div class="action-buttons">
|
||
<button
|
||
@click="startBasicAnalysis"
|
||
class="analysis-button"
|
||
:disabled="isBasicAnalysisLoading"
|
||
>
|
||
{{ isBasicAnalysisLoading ? '基础分析中...' : '基础信息分析' }}
|
||
</button>
|
||
<button
|
||
@click="startSopAnalysis"
|
||
class="analysis-button sop-button"
|
||
:disabled="isSopAnalysisLoading"
|
||
>
|
||
{{ isSopAnalysisLoading ? 'SOP分析中...' : 'SOP通话分析' }}
|
||
</button>
|
||
<button
|
||
@click="startDemandAnalysis"
|
||
class="analysis-button demand-button"
|
||
:disabled="isDemandAnalysisLoading"
|
||
>
|
||
{{ isDemandAnalysisLoading ? '诉求分析中...' : '客户诉求分析' }}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 分析区域 -->
|
||
<div class="analysis-areas">
|
||
<!-- 上方两个区域 -->
|
||
<div class="top-row">
|
||
<!-- 基础信息分析 -->
|
||
<div class="analysis-section basic-analysis">
|
||
<div class="section-header">
|
||
<h4>基础信息分析</h4>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="text-content" v-if="basicAnalysisResult">
|
||
<div class="analysis-text" v-html="formattedBasicAnalysis"></div>
|
||
</div>
|
||
<div class="placeholder-text" v-else>
|
||
<p>点击"基础信息分析"按钮开始分析客户基础信息</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SOP通话分析 -->
|
||
<div class="analysis-section sop-analysis">
|
||
<div class="section-header">
|
||
<h4>SOP通话分析</h4>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="text-content" v-if="sopAnalysisResult">
|
||
<div class="analysis-text" v-html="formattedSopAnalysis"></div>
|
||
</div>
|
||
<div class="placeholder-text" v-else>
|
||
<p>点击"SOP通话分析"按钮开始分析通话记录</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 下方整行区域 -->
|
||
<div class="bottom-row">
|
||
<!-- 客户诉求分析 -->
|
||
<div class="analysis-section demand-analysis">
|
||
<div class="section-header">
|
||
<h4>客户诉求分析</h4>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="text-content" v-if="demandAnalysisResult">
|
||
<div class="analysis-text" v-html="formattedDemandAnalysis"></div>
|
||
</div>
|
||
<div class="placeholder-text" v-else>
|
||
<p>点击"客户诉求分析"按钮开始深度分析客户需求和诉求</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 未选择客户时的提示 -->
|
||
<div v-else class="no-selection">
|
||
<p>请选择一个客户查看详情</p>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, watch, computed } from 'vue';
|
||
import { SimpleChatService } from '@/utils/ChatService.js';
|
||
import MarkdownIt from 'markdown-it';
|
||
|
||
// 定义props
|
||
const props = defineProps({
|
||
selectedContact: {
|
||
type: Object,
|
||
default: null
|
||
}
|
||
});
|
||
|
||
// 分析结果状态
|
||
const basicAnalysisResult = ref(''); // 基础信息分析结果
|
||
const sopAnalysisResult = ref(''); // SOP通话分析结果
|
||
const demandAnalysisResult = ref(''); // 客户诉求分析结果
|
||
|
||
// 加载状态
|
||
const isBasicAnalysisLoading = ref(false); // 基础分析加载状态
|
||
const isSopAnalysisLoading = ref(false); // SOP分析加载状态
|
||
const isDemandAnalysisLoading = ref(false); // 诉求分析加载状态
|
||
|
||
// Dify API配置
|
||
const DIFY_API_KEY_01 = 'app-wbR1P1j6kvdBK8Q1qXzdswzP';
|
||
const DIFY_API_KEY = 'app-37VXHRieOnq17BSury9ONavG';
|
||
// 初始化ChatService
|
||
const chatService_01 = new SimpleChatService(DIFY_API_KEY_01);
|
||
const chatService = new SimpleChatService(DIFY_API_KEY);
|
||
|
||
// 初始化markdown-it
|
||
const md = new MarkdownIt({
|
||
html: true,
|
||
linkify: true,
|
||
typographer: true
|
||
});
|
||
|
||
// 计算属性:格式化基础分析结果
|
||
const formattedBasicAnalysis = computed(() => {
|
||
if (!basicAnalysisResult.value) return '';
|
||
return md.render(basicAnalysisResult.value);
|
||
});
|
||
|
||
// 计算属性:格式化SOP分析结果
|
||
const formattedSopAnalysis = computed(() => {
|
||
if (!sopAnalysisResult.value) return '';
|
||
return md.render(sopAnalysisResult.value);
|
||
});
|
||
|
||
// 计算属性:格式化诉求分析结果
|
||
const formattedDemandAnalysis = computed(() => {
|
||
if (!demandAnalysisResult.value) return '';
|
||
return md.render(demandAnalysisResult.value);
|
||
});
|
||
|
||
// 监听selectedContact变化,重置所有分析结果
|
||
watch(() => props.selectedContact, (newContact) => {
|
||
if (newContact) {
|
||
// 重置所有分析状态
|
||
basicAnalysisResult.value = '';
|
||
sopAnalysisResult.value = '';
|
||
demandAnalysisResult.value = '';
|
||
isBasicAnalysisLoading.value = false;
|
||
isSopAnalysisLoading.value = false;
|
||
isDemandAnalysisLoading.value = false;
|
||
} else {
|
||
// 清空所有结果
|
||
basicAnalysisResult.value = '';
|
||
sopAnalysisResult.value = '';
|
||
demandAnalysisResult.value = '';
|
||
isBasicAnalysisLoading.value = false;
|
||
isSopAnalysisLoading.value = false;
|
||
isDemandAnalysisLoading.value = false;
|
||
}
|
||
}, { immediate: true });
|
||
|
||
// 基础信息分析
|
||
const startBasicAnalysis = async () => {
|
||
if (!props.selectedContact) return;
|
||
|
||
isBasicAnalysisLoading.value = true;
|
||
basicAnalysisResult.value = '';
|
||
|
||
const query = `请对客户进行基础信息分析:
|
||
客户姓名:${props.selectedContact.name}
|
||
联系电话:${props.selectedContact.phone || '未提供'}
|
||
邮箱:${props.selectedContact.email || '未提供'}
|
||
公司:${props.selectedContact.company || '未提供'}
|
||
职位:${props.selectedContact.position || '未提供'}
|
||
销售阶段:${props.selectedContact.salesStage || '未知'}
|
||
健康度:${props.selectedContact.health || '未知'}%
|
||
|
||
请分析客户的基本情况、背景信息和初步画像。`;
|
||
|
||
try {
|
||
await chatService_01.sendMessage(
|
||
query,
|
||
(update) => {
|
||
basicAnalysisResult.value = update.content;
|
||
},
|
||
() => {
|
||
isBasicAnalysisLoading.value = false;
|
||
console.log('基础信息分析完成');
|
||
}
|
||
);
|
||
} catch (error) {
|
||
console.error('基础信息分析失败:', error);
|
||
basicAnalysisResult.value = `分析失败: ${error.message}`;
|
||
isBasicAnalysisLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// SOP通话分析
|
||
const startSopAnalysis = async () => {
|
||
if (!props.selectedContact) return;
|
||
|
||
isSopAnalysisLoading.value = true;
|
||
sopAnalysisResult.value = '';
|
||
|
||
const query = `请对客户 ${props.selectedContact.name} 进行SOP通话分析:
|
||
|
||
基于标准销售流程(SOP),分析以下方面:
|
||
1. 通话质量评估
|
||
2. 销售流程执行情况
|
||
3. 客户响应度分析
|
||
4. 沟通效果评价
|
||
5. 改进建议
|
||
|
||
客户当前状态:${props.selectedContact.salesStage || '未知'}
|
||
健康度:${props.selectedContact.health || '未知'}%`;
|
||
|
||
try {
|
||
await chatService.sendMessage(
|
||
query,
|
||
(update) => {
|
||
sopAnalysisResult.value = update.content;
|
||
},
|
||
() => {
|
||
isSopAnalysisLoading.value = false;
|
||
console.log('SOP通话分析完成');
|
||
}
|
||
);
|
||
} catch (error) {
|
||
console.error('SOP通话分析失败:', error);
|
||
sopAnalysisResult.value = `分析失败: ${error.message}`;
|
||
isSopAnalysisLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 客户诉求分析
|
||
const startDemandAnalysis = async () => {
|
||
if (!props.selectedContact) return;
|
||
|
||
isDemandAnalysisLoading.value = true;
|
||
demandAnalysisResult.value = '';
|
||
|
||
const query = `请对客户 ${props.selectedContact.name} 进行深度诉求分析:
|
||
|
||
请从以下维度分析客户的真实需求和诉求:
|
||
1. 显性需求分析(客户明确表达的需求)
|
||
2. 隐性需求挖掘(潜在的、未明确表达的需求)
|
||
3. 痛点识别(客户面临的主要问题和挑战)
|
||
4. 决策因素分析(影响客户决策的关键因素)
|
||
5. 价值期望(客户期望获得的价值和收益)
|
||
6. 风险顾虑(客户可能的担忧和顾虑)
|
||
7. 个性化建议(针对性的解决方案建议)
|
||
|
||
客户信息:
|
||
姓名:${props.selectedContact.name}
|
||
公司:${props.selectedContact.company || '未提供'}
|
||
职位:${props.selectedContact.position || '未提供'}
|
||
销售阶段:${props.selectedContact.salesStage || '未知'}
|
||
健康度:${props.selectedContact.health || '未知'}%`;
|
||
|
||
try {
|
||
await chatService.sendMessage(
|
||
query,
|
||
(update) => {
|
||
demandAnalysisResult.value = update.content;
|
||
},
|
||
() => {
|
||
isDemandAnalysisLoading.value = false;
|
||
console.log('客户诉求分析完成');
|
||
}
|
||
);
|
||
} catch (error) {
|
||
console.error('客户诉求分析失败:', error);
|
||
demandAnalysisResult.value = `分析失败: ${error.message}`;
|
||
isDemandAnalysisLoading.value = false;
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
// Color Palette
|
||
$slate-50: #f8fafc;
|
||
$slate-100: #f1f5f9;
|
||
$slate-200: #e2e8f0;
|
||
$slate-300: #cbd5e1;
|
||
$slate-400: #94a3b8;
|
||
$slate-500: #64748b;
|
||
$slate-600: #475569;
|
||
$slate-700: #334155;
|
||
$slate-800: #1e293b;
|
||
$white: #ffffff;
|
||
|
||
$blue: #3b82f6;
|
||
$green: #22c55e;
|
||
$amber: #f59e0b;
|
||
$red: #ef4444;
|
||
$indigo: #4f46e5;
|
||
$purple: #a855f7;
|
||
|
||
// 容器样式
|
||
.customer-detail-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
padding: 16px;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
// padding: 24px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
padding: 20px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
padding: 12px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
padding: 8px;
|
||
}
|
||
}
|
||
|
||
// 客户详情内容
|
||
.customer-detail-content {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
|
||
// 客户头部信息
|
||
.customer-header {
|
||
background: $white;
|
||
border-radius: 8px;
|
||
padding: 16px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
border: 1px solid $slate-200;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
padding: 20px;
|
||
border-radius: 12px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
padding: 18px;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 16px;
|
||
padding: 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
padding: 12px;
|
||
gap: 12px;
|
||
}
|
||
|
||
h3 {
|
||
margin: 0;
|
||
color: $slate-800;
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
font-size: 24px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
font-size: 22px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
font-size: 18px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
font-size: 16px;
|
||
}
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
gap: 12px;
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
width: 100%;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
gap: 6px;
|
||
}
|
||
|
||
.analysis-button {
|
||
padding: 10px 16px;
|
||
background: $blue;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
transition: all 0.2s ease;
|
||
white-space: nowrap;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
padding: 12px 20px;
|
||
font-size: 15px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
padding: 11px 18px;
|
||
font-size: 14px;
|
||
border-radius: 7px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
width: 100%;
|
||
padding: 12px 16px;
|
||
font-size: 14px;
|
||
text-align: center;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
padding: 10px 12px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
&:hover:not(:disabled) {
|
||
background: #2563eb;
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
&:disabled {
|
||
background: $slate-400;
|
||
cursor: not-allowed;
|
||
transform: none;
|
||
}
|
||
|
||
&.sop-button {
|
||
background: $green;
|
||
|
||
&:hover:not(:disabled) {
|
||
background: #16a34a;
|
||
}
|
||
}
|
||
|
||
&.demand-button {
|
||
background: $purple;
|
||
|
||
&:hover:not(:disabled) {
|
||
background: #9333ea;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 分析区域
|
||
.analysis-areas {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
min-height: 0;
|
||
}
|
||
|
||
// 上方行
|
||
.top-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
height: 45%;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
gap: 20px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
gap: 18px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
grid-template-columns: 1fr;
|
||
height: auto;
|
||
gap: 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
gap: 12px;
|
||
}
|
||
}
|
||
|
||
// 下方行
|
||
.bottom-row {
|
||
height: 55%;
|
||
}
|
||
|
||
// 分析区域样式
|
||
.analysis-section {
|
||
background: $white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
border: 1px solid $slate-200;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
border-radius: 12px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
border-radius: 10px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
min-height: 300px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
min-height: 250px;
|
||
}
|
||
|
||
.section-header {
|
||
padding: 12px 16px;
|
||
background: $slate-50;
|
||
border-bottom: 1px solid $slate-200;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
padding: 16px 20px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
padding: 14px 18px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
padding: 12px 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
padding: 10px 12px;
|
||
}
|
||
|
||
h4 {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: $slate-700;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
font-size: 18px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
font-size: 17px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
font-size: 15px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.section-content {
|
||
flex: 1;
|
||
padding: 16px;
|
||
overflow-y: auto;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
padding: 20px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
padding: 18px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
padding: 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
padding: 12px;
|
||
}
|
||
|
||
.text-content {
|
||
height: 100%;
|
||
|
||
.analysis-text {
|
||
color: $slate-700;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
word-wrap: break-word;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
font-size: 15px;
|
||
line-height: 1.7;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
font-size: 14px;
|
||
line-height: 1.65;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
}
|
||
|
||
.placeholder-text {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
background: $slate-50;
|
||
border-radius: 6px;
|
||
border: 2px dashed $slate-200;
|
||
|
||
p {
|
||
margin: 0;
|
||
color: $slate-500;
|
||
font-size: 14px;
|
||
text-align: center;
|
||
padding: 16px;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
font-size: 15px;
|
||
padding: 20px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
font-size: 14px;
|
||
padding: 18px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
font-size: 13px;
|
||
padding: 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
font-size: 12px;
|
||
padding: 12px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 不同分析区域的主题色
|
||
&.basic-analysis {
|
||
.section-header {
|
||
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
||
|
||
h4 {
|
||
color: $blue;
|
||
}
|
||
}
|
||
}
|
||
|
||
&.sop-analysis {
|
||
.section-header {
|
||
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
|
||
|
||
h4 {
|
||
color: $green;
|
||
}
|
||
}
|
||
}
|
||
|
||
&.demand-analysis {
|
||
.section-header {
|
||
background: linear-gradient(135deg, #faf5ff 0%, #f3e8ff 100%);
|
||
|
||
h4 {
|
||
color: $purple;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Markdown样式
|
||
.analysis-text {
|
||
// Markdown样式
|
||
h1, h2, h3, h4, h5, h6 {
|
||
margin: 1rem 0 0.5rem 0;
|
||
font-weight: 600;
|
||
color: $slate-800;
|
||
|
||
&:first-child {
|
||
margin-top: 0;
|
||
}
|
||
}
|
||
|
||
h1 { font-size: 1.25rem; }
|
||
h2 { font-size: 1.125rem; }
|
||
h3 { font-size: 1rem; }
|
||
h4 { font-size: 0.875rem; }
|
||
h5 { font-size: 0.75rem; }
|
||
h6 { font-size: 0.75rem; }
|
||
|
||
p {
|
||
margin: 0.5rem 0;
|
||
|
||
&:first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
ul, ol {
|
||
margin: 0.5rem 0;
|
||
padding-left: 1.5rem;
|
||
|
||
li {
|
||
margin: 0.25rem 0;
|
||
}
|
||
}
|
||
|
||
blockquote {
|
||
margin: 1rem 0;
|
||
padding: 0.5rem 1rem;
|
||
border-left: 4px solid $blue;
|
||
background: rgba(59, 130, 246, 0.05);
|
||
font-style: italic;
|
||
}
|
||
|
||
code {
|
||
background: $slate-100;
|
||
padding: 0.125rem 0.25rem;
|
||
border-radius: 0.25rem;
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
pre {
|
||
background: $slate-100;
|
||
padding: 1rem;
|
||
border-radius: 0.5rem;
|
||
overflow-x: auto;
|
||
margin: 1rem 0;
|
||
|
||
code {
|
||
background: none;
|
||
padding: 0;
|
||
}
|
||
}
|
||
|
||
strong {
|
||
font-weight: 600;
|
||
color: $slate-800;
|
||
}
|
||
|
||
em {
|
||
font-style: italic;
|
||
}
|
||
|
||
a {
|
||
color: $blue;
|
||
text-decoration: none;
|
||
|
||
&:hover {
|
||
text-decoration: underline;
|
||
}
|
||
}
|
||
|
||
hr {
|
||
margin: 1.5rem 0;
|
||
border: none;
|
||
border-top: 1px solid $slate-200;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 1rem 0;
|
||
|
||
th, td {
|
||
padding: 0.5rem;
|
||
border: 1px solid $slate-200;
|
||
text-align: left;
|
||
}
|
||
|
||
th {
|
||
background: $slate-50;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 未选择状态
|
||
.no-selection {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
background: $slate-50;
|
||
border-radius: 8px;
|
||
border: 2px dashed $slate-200;
|
||
color: $slate-500;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
border-radius: 12px;
|
||
min-height: 500px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
border-radius: 10px;
|
||
min-height: 450px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
height: 400px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
height: 300px;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
font-size: 1rem;
|
||
text-align: center;
|
||
padding: 1rem;
|
||
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
font-size: 1.125rem;
|
||
padding: 1.5rem;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
font-size: 1.0625rem;
|
||
padding: 1.25rem;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
font-size: 0.875rem;
|
||
padding: 1rem;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
font-size: 0.75rem;
|
||
padding: 0.75rem;
|
||
}
|
||
}
|
||
}
|
||
|
||
h2.section-title {
|
||
font-size: 1.25rem;
|
||
font-weight: bold;
|
||
color: $slate-700;
|
||
}
|
||
|
||
h4 {
|
||
font-weight: 600;
|
||
color: $slate-700;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
// Context Panel
|
||
.section-card {
|
||
background-color: $white;
|
||
border-radius: 0.5rem;
|
||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||
// padding: 1rem;
|
||
// margin-top: 12px;
|
||
}
|
||
|
||
// 分析区域布局优化
|
||
.analysis-areas {
|
||
// PC端保持一致布局
|
||
@media (min-width: 1024px) {
|
||
gap: 20px;
|
||
}
|
||
|
||
// 平板端适配
|
||
@media (max-width: 1023px) and (min-width: 769px) {
|
||
gap: 18px;
|
||
}
|
||
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
gap: 16px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
gap: 12px;
|
||
}
|
||
}
|
||
|
||
// 下方行适配
|
||
.bottom-row {
|
||
// 移动端适配
|
||
@media (max-width: 768px) {
|
||
height: auto;
|
||
min-height: 300px;
|
||
}
|
||
|
||
// 小屏移动端适配
|
||
@media (max-width: 480px) {
|
||
min-height: 250px;
|
||
}
|
||
}
|
||
|
||
</style> |