<template>
|
<div class="market-analysis-container">
|
|
<!-- 数据概览卡片 -->
|
<el-row :gutter="20" class="data-overview">
|
<el-col :span="6">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon price-icon">
|
<el-icon><TrendCharts /></el-icon>
|
</div>
|
<div class="card-info">
|
<div class="card-title">平均煤价</div>
|
<div class="card-value">¥{{ marketData.avgPrice.toFixed(2) }}</div>
|
<div class="card-change" :class="marketData.priceChange >= 0 ? 'positive' : 'negative'">
|
{{ marketData.priceChange >= 0 ? '+' : '' }}{{ marketData.priceChange.toFixed(2) }}%
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<el-col :span="6">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon volume-icon">
|
<el-icon><DataLine /></el-icon>
|
</div>
|
<div class="card-info">
|
<div class="card-title">交易量</div>
|
<div class="card-value">{{ marketData.totalVolume }}万吨</div>
|
<div class="card-change" :class="marketData.volumeChange >= 0 ? 'positive' : 'negative'">
|
{{ marketData.volumeChange >= 0 ? '+' : '' }}{{ marketData.volumeChange.toFixed(2) }}%
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<el-col :span="6">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon customer-icon">
|
<el-icon><User /></el-icon>
|
</div>
|
<div class="card-info">
|
<div class="card-title">活跃客户</div>
|
<div class="card-value">{{ marketData.activeCustomers }}家</div>
|
<div class="card-change" :class="marketData.customerChange >= 0 ? 'positive' : 'negative'">
|
{{ marketData.customerChange >= 0 ? '+' : '' }}{{ marketData.customerChange.toFixed(2) }}%
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<el-col :span="6">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon trend-icon">
|
<el-icon><TrendCharts /></el-icon>
|
</div>
|
<div class="card-info">
|
<div class="card-title">市场趋势</div>
|
<div class="card-value">{{ marketData.marketTrend }}</div>
|
<div class="card-change" :class="marketData.trendScore >= 0 ? 'positive' : 'negative'">
|
信心指数: {{ marketData.trendScore }}
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 主要分析区域 -->
|
<el-row :gutter="20" class="main-analysis">
|
<!-- 价格趋势分析 -->
|
<el-col :span="16">
|
<el-card class="analysis-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>煤种价格趋势分析</span>
|
<div class="header-controls">
|
<el-select v-model="selectedCoalType" placeholder="选择煤种" size="small" style="width: 120px">
|
<el-option label="混煤" value="mixed" />
|
<el-option label="精煤" value="refined" />
|
<el-option label="动力煤" value="power" />
|
<el-option label="焦煤" value="coking" />
|
</el-select>
|
<el-select v-model="selectedRegion" placeholder="选择产地" size="small" style="width: 120px">
|
<el-option label="山西" value="shanxi" />
|
<el-option label="内蒙古" value="neimenggu" />
|
<el-option label="陕西" value="shaanxi" />
|
<el-option label="新疆" value="xinjiang" />
|
</el-select>
|
<el-select v-model="selectedPeriod" placeholder="时间周期" size="small" style="width: 100px">
|
<el-option label="日" value="day" />
|
<el-option label="周" value="week" />
|
<el-option label="月" value="month" />
|
<el-option label="季" value="quarter" />
|
</el-select>
|
</div>
|
</div>
|
</template>
|
|
<div class="chart-container">
|
<div ref="priceChartRef" class="chart" style="height: 400px;"></div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<!-- 客户行为分析 -->
|
<el-col :span="8">
|
<el-card class="analysis-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>客户行为画像</span>
|
</div>
|
</template>
|
|
<div class="customer-analysis">
|
<div class="customer-type-distribution">
|
<h4>客户类型分布</h4>
|
<div ref="customerChartRef" class="chart" style="height: 200px;"></div>
|
</div>
|
|
<div class="purchase-preference">
|
<h4>采购偏好分析</h4>
|
<div class="preference-item" v-for="item in customerPreferences" :key="item.type">
|
<div class="preference-label">{{ item.type }}</div>
|
<div class="preference-bar">
|
<div class="bar-fill" :style="{ width: item.percentage + '%' }"></div>
|
</div>
|
<div class="preference-value">{{ item.percentage }}%</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 详细分析区域 -->
|
<el-row :gutter="20" class="detail-analysis">
|
<!-- 区域价格对比 -->
|
<el-col :span="12">
|
<el-card class="analysis-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>区域价格对比</span>
|
</div>
|
</template>
|
|
<div class="region-comparison">
|
<div ref="regionChartRef" class="chart" style="height: 300px;"></div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<!-- 客户采购周期分析 -->
|
<el-col :span="12">
|
<el-card class="analysis-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>客户采购周期分析</span>
|
</div>
|
</template>
|
|
<div class="purchase-cycle">
|
<div ref="cycleChartRef" class="chart" style="height: 300px;"></div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 智能推荐区域 -->
|
<el-row :gutter="20" class="smart-recommendations">
|
<el-col :span="24">
|
<el-card class="analysis-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>智能营销推荐</span>
|
<el-tag type="warning" size="small">AI算法驱动</el-tag>
|
</div>
|
</template>
|
|
<div class="recommendations-content">
|
<el-row :gutter="20">
|
<el-col :span="8">
|
<div class="recommendation-section">
|
<h4>个性化定价建议</h4>
|
<div class="pricing-suggestions">
|
<div class="suggestion-item" v-for="suggestion in pricingSuggestions" :key="suggestion.id">
|
<div class="suggestion-header">
|
<span class="customer-name">{{ suggestion.customerName }}</span>
|
<el-tag :type="suggestion.priority" size="small">{{ suggestion.priorityText }}</el-tag>
|
</div>
|
<div class="suggestion-content">
|
<p>建议价格:¥{{ suggestion.suggestedPrice }}/吨</p>
|
<p>议价空间:{{ suggestion.negotiationSpace }}%</p>
|
<p>推单时机:{{ suggestion.timing }}</p>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-col>
|
|
<el-col :span="8">
|
<div class="recommendation-section">
|
<h4>热销煤型推荐</h4>
|
<div class="hot-coal-types">
|
<div class="coal-type-item" v-for="coal in hotCoalTypes" :key="coal.id">
|
<div class="coal-info">
|
<div class="coal-name">{{ coal.name }}</div>
|
<div class="coal-spec">{{ coal.specification }}</div>
|
</div>
|
<div class="coal-metrics">
|
<div class="metric">
|
<span class="label">热度指数:</span>
|
<span class="value">{{ coal.heatIndex }}</span>
|
</div>
|
<div class="metric">
|
<span class="label">库存状态:</span>
|
<el-tag :type="coal.stockStatus === '充足' ? 'success' : 'warning'" size="small">
|
{{ coal.stockStatus }}
|
</el-tag>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-col>
|
|
<el-col :span="8">
|
<div class="recommendation-section">
|
<h4>客户粘性提升</h4>
|
<div class="loyalty-improvements">
|
<div class="improvement-item" v-for="improvement in loyaltyImprovements" :key="improvement.id">
|
<div class="improvement-header">
|
<span class="strategy-name">{{ improvement.strategyName }}</span>
|
<span class="success-rate">成功率: {{ improvement.successRate }}%</span>
|
</div>
|
<div class="improvement-content">
|
<p>{{ improvement.description }}</p>
|
<div class="action-buttons">
|
<el-button type="primary" size="small">执行策略</el-button>
|
<el-button size="small">查看详情</el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
|
import { ElMessage } from 'element-plus'
|
import { Refresh, TrendCharts, DataLine, User } from '@element-plus/icons-vue'
|
import * as echarts from 'echarts'
|
|
// 响应式数据
|
const refreshing = ref(false)
|
const lastUpdateTime = ref('')
|
const selectedCoalType = ref('mixed')
|
const selectedRegion = ref('shanxi')
|
const selectedPeriod = ref('month')
|
|
// 图表引用
|
const priceChartRef = ref(null)
|
const customerChartRef = ref(null)
|
const regionChartRef = ref(null)
|
const cycleChartRef = ref(null)
|
|
// 图表实例
|
let priceChart = null
|
let customerChart = null
|
let regionChart = null
|
let cycleChart = null
|
|
// 市场数据
|
const marketData = reactive({
|
avgPrice: 1250.50,
|
priceChange: 2.35,
|
totalVolume: 1250.8,
|
volumeChange: -1.25,
|
activeCustomers: 156,
|
customerChange: 3.45,
|
marketTrend: '稳中有升',
|
trendScore: 8.5
|
})
|
|
// 客户偏好数据
|
const customerPreferences = ref([
|
{ type: '焦化厂', percentage: 35 },
|
{ type: '电厂', percentage: 28 },
|
{ type: '钢厂', percentage: 22 },
|
{ type: '化工厂', percentage: 15 }
|
])
|
|
// 定价建议
|
const pricingSuggestions = ref([
|
{
|
id: 1,
|
customerName: '山西焦化集团',
|
priority: 'high',
|
priorityText: '高优先级',
|
suggestedPrice: 1280,
|
negotiationSpace: 5.2,
|
timing: '本周内'
|
},
|
{
|
id: 2,
|
customerName: '华能电力',
|
priority: 'medium',
|
priorityText: '中优先级',
|
suggestedPrice: 1250,
|
negotiationSpace: 3.8,
|
timing: '下周初'
|
},
|
{
|
id: 3,
|
customerName: '宝钢集团',
|
priority: 'low',
|
priorityText: '低优先级',
|
suggestedPrice: 1220,
|
negotiationSpace: 2.5,
|
timing: '本月内'
|
}
|
])
|
|
// 热销煤型
|
const hotCoalTypes = ref([
|
{
|
id: 1,
|
name: '优质混煤',
|
specification: '发热量5500大卡',
|
heatIndex: 9.2,
|
stockStatus: '充足'
|
},
|
{
|
id: 2,
|
name: '精洗焦煤',
|
specification: '灰分≤8%',
|
heatIndex: 8.8,
|
stockStatus: '充足'
|
},
|
{
|
id: 3,
|
name: '动力煤',
|
specification: '发热量6000大卡',
|
heatIndex: 8.5,
|
stockStatus: '紧张'
|
}
|
])
|
|
// 客户粘性提升策略
|
const loyaltyImprovements = ref([
|
{
|
id: 1,
|
strategyName: '差异化定价策略',
|
successRate: 85,
|
description: '根据客户采购频次和议价能力,制定个性化价格方案'
|
},
|
{
|
id: 2,
|
strategyName: '精准推单节奏',
|
successRate: 78,
|
description: '基于客户采购周期分析,在最佳时机推送相关产品'
|
},
|
{
|
id: 3,
|
strategyName: '增值服务包',
|
successRate: 92,
|
description: '提供物流配送、质量检测等增值服务,提升客户满意度'
|
}
|
])
|
|
// 模拟数据生成
|
const generateMockData = () => {
|
// 生成价格趋势数据
|
const dates = []
|
const prices = []
|
const volumes = []
|
|
for (let i = 30; i >= 0; i--) {
|
const date = new Date()
|
date.setDate(date.getDate() - i)
|
dates.push(date.toLocaleDateString())
|
|
const basePrice = 1200 + Math.random() * 200
|
prices.push(basePrice)
|
|
const baseVolume = 30 + Math.random() * 20
|
volumes.push(baseVolume)
|
}
|
|
return { dates, prices, volumes }
|
}
|
|
// 初始化价格趋势图表
|
const initPriceChart = () => {
|
if (!priceChartRef.value) return
|
|
priceChart = echarts.init(priceChartRef.value)
|
const { dates, prices, volumes } = generateMockData()
|
|
const option = {
|
title: {
|
text: '混煤月度价格变化趋势',
|
left: 'center',
|
textStyle: {
|
fontSize: 16,
|
fontWeight: 'bold'
|
}
|
},
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'cross'
|
}
|
},
|
legend: {
|
data: ['价格(元/吨)', '交易量(万吨)'],
|
top: 30
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: dates,
|
axisLabel: {
|
rotate: 45
|
}
|
},
|
yAxis: [
|
{
|
type: 'value',
|
name: '价格(元/吨)',
|
position: 'left'
|
},
|
{
|
type: 'value',
|
name: '交易量(万吨)',
|
position: 'right'
|
}
|
],
|
series: [
|
{
|
name: '价格(元/吨)',
|
type: 'line',
|
data: prices,
|
smooth: true,
|
lineStyle: {
|
color: '#409EFF',
|
width: 3
|
},
|
itemStyle: {
|
color: '#409EFF'
|
}
|
},
|
{
|
name: '交易量(万吨)',
|
type: 'bar',
|
yAxisIndex: 1,
|
data: volumes,
|
itemStyle: {
|
color: '#67C23A'
|
}
|
}
|
]
|
}
|
|
priceChart.setOption(option)
|
}
|
|
// 初始化客户分布图表
|
const initCustomerChart = () => {
|
if (!customerChartRef.value) return
|
|
customerChart = echarts.init(customerChartRef.value)
|
|
const option = {
|
tooltip: {
|
trigger: 'item',
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
},
|
series: [
|
{
|
name: '客户类型',
|
type: 'pie',
|
radius: ['40%', '70%'],
|
avoidLabelOverlap: false,
|
label: {
|
show: false,
|
position: 'center'
|
},
|
emphasis: {
|
label: {
|
show: true,
|
fontSize: '18',
|
fontWeight: 'bold'
|
}
|
},
|
labelLine: {
|
show: false
|
},
|
data: [
|
{ value: 35, name: '焦化厂' },
|
{ value: 28, name: '电厂' },
|
{ value: 22, name: '钢厂' },
|
{ value: 15, name: '化工厂' }
|
]
|
}
|
]
|
}
|
|
customerChart.setOption(option)
|
}
|
|
// 初始化区域对比图表
|
const initRegionChart = () => {
|
if (!regionChartRef.value) return
|
|
regionChart = echarts.init(regionChartRef.value)
|
|
const option = {
|
title: {
|
text: '各产地煤价对比',
|
left: 'center'
|
},
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
}
|
},
|
legend: {
|
data: ['混煤', '精煤', '动力煤', '焦煤'],
|
top: 30
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: ['山西', '内蒙古', '陕西', '新疆']
|
},
|
yAxis: {
|
type: 'value',
|
name: '价格(元/吨)'
|
},
|
series: [
|
{
|
name: '混煤',
|
type: 'bar',
|
data: [1250, 1180, 1220, 1150]
|
},
|
{
|
name: '精煤',
|
type: 'bar',
|
data: [1350, 1280, 1320, 1250]
|
},
|
{
|
name: '动力煤',
|
type: 'bar',
|
data: [1150, 1080, 1120, 1050]
|
},
|
{
|
name: '焦煤',
|
type: 'bar',
|
data: [1450, 1380, 1420, 1350]
|
}
|
]
|
}
|
|
regionChart.setOption(option)
|
}
|
|
// 初始化采购周期图表
|
const initCycleChart = () => {
|
if (!cycleChartRef.value) return
|
|
cycleChart = echarts.init(cycleChartRef.value)
|
|
const option = {
|
title: {
|
text: '客户采购周期分布',
|
left: 'center'
|
},
|
tooltip: {
|
trigger: 'item'
|
},
|
series: [
|
{
|
name: '采购周期',
|
type: 'funnel',
|
left: '10%',
|
top: 60,
|
bottom: 60,
|
width: '80%',
|
height: '80%',
|
min: 0,
|
max: 100,
|
minSize: '0%',
|
maxSize: '100%',
|
sort: 'descending',
|
gap: 2,
|
label: {
|
show: true,
|
position: 'inside'
|
},
|
labelLine: {
|
length: 10,
|
lineStyle: {
|
width: 1,
|
type: 'solid'
|
}
|
},
|
itemStyle: {
|
borderColor: '#fff',
|
borderWidth: 1
|
},
|
emphasis: {
|
label: {
|
fontSize: 20
|
}
|
},
|
data: [
|
{ value: 100, name: '高频客户(周采购)' },
|
{ value: 80, name: '中频客户(月采购)' },
|
{ value: 60, name: '低频客户(季采购)' },
|
{ value: 40, name: '偶发客户(年采购)' }
|
]
|
}
|
]
|
}
|
|
cycleChart.setOption(option)
|
}
|
|
// 刷新数据
|
const refreshData = async () => {
|
refreshing.value = true
|
|
try {
|
// 模拟数据刷新
|
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
// 更新市场数据
|
marketData.avgPrice = 1200 + Math.random() * 200
|
marketData.priceChange = (Math.random() - 0.5) * 10
|
marketData.totalVolume = 1000 + Math.random() * 500
|
marketData.volumeChange = (Math.random() - 0.5) * 8
|
marketData.activeCustomers = 140 + Math.floor(Math.random() * 40)
|
marketData.customerChange = (Math.random() - 0.5) * 6
|
marketData.trendScore = 7 + Math.random() * 3
|
|
// 更新时间
|
lastUpdateTime.value = new Date().toLocaleString()
|
|
// 重新初始化图表
|
await nextTick()
|
initPriceChart()
|
initCustomerChart()
|
initRegionChart()
|
initCycleChart()
|
|
ElMessage.success('数据刷新成功')
|
} catch (error) {
|
ElMessage.error('数据刷新失败')
|
} finally {
|
refreshing.value = false
|
}
|
}
|
|
// 自动刷新定时器
|
let refreshTimer = null
|
|
// 启动自动刷新
|
const startAutoRefresh = () => {
|
refreshTimer = setInterval(() => {
|
refreshData()
|
}, 10 * 60 * 1000) // 10分钟
|
}
|
|
// 停止自动刷新
|
const stopAutoRefresh = () => {
|
if (refreshTimer) {
|
clearInterval(refreshTimer)
|
refreshTimer = null
|
}
|
}
|
|
// 监听窗口大小变化
|
const handleResize = () => {
|
if (priceChart) priceChart.resize()
|
if (customerChart) customerChart.resize()
|
if (regionChart) regionChart.resize()
|
if (cycleChart) cycleChart.resize()
|
}
|
|
// 生命周期
|
onMounted(async () => {
|
// 初始化时间
|
lastUpdateTime.value = new Date().toLocaleString()
|
|
// 等待DOM渲染完成
|
await nextTick()
|
|
// 初始化图表
|
initPriceChart()
|
initCustomerChart()
|
initRegionChart()
|
initCycleChart()
|
|
// 启动自动刷新
|
startAutoRefresh()
|
|
// 监听窗口大小变化
|
window.addEventListener('resize', handleResize)
|
})
|
|
onUnmounted(() => {
|
// 停止自动刷新
|
stopAutoRefresh()
|
|
// 销毁图表
|
if (priceChart) priceChart.dispose()
|
if (customerChart) customerChart.dispose()
|
if (regionChart) regionChart.dispose()
|
if (cycleChart) cycleChart.dispose()
|
|
// 移除事件监听
|
window.removeEventListener('resize', handleResize)
|
})
|
</script>
|
|
<style scoped>
|
.market-analysis-container {
|
padding: 20px;
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
}
|
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding: 20px;
|
background: white;
|
border-radius: 8px;
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
}
|
|
.page-header h1 {
|
margin: 0;
|
color: #303133;
|
font-size: 24px;
|
font-weight: 600;
|
}
|
|
.header-info {
|
display: flex;
|
align-items: center;
|
gap: 15px;
|
}
|
|
.update-time {
|
color: #909399;
|
font-size: 14px;
|
}
|
|
.data-overview {
|
margin-bottom: 20px;
|
}
|
|
.overview-card {
|
height: 120px;
|
}
|
|
.card-content {
|
display: flex;
|
align-items: center;
|
height: 100%;
|
}
|
|
.card-icon {
|
width: 60px;
|
height: 60px;
|
border-radius: 50%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-right: 15px;
|
font-size: 24px;
|
color: white;
|
}
|
|
.price-icon {
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
}
|
|
.volume-icon {
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
}
|
|
.customer-icon {
|
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
}
|
|
.trend-icon {
|
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
}
|
|
.card-info {
|
flex: 1;
|
}
|
|
.card-title {
|
font-size: 14px;
|
color: #909399;
|
margin-bottom: 8px;
|
}
|
|
.card-value {
|
font-size: 24px;
|
font-weight: 600;
|
color: #303133;
|
margin-bottom: 8px;
|
}
|
|
.card-change {
|
font-size: 12px;
|
font-weight: 500;
|
}
|
|
.card-change.positive {
|
color: #67c23a;
|
}
|
|
.card-change.negative {
|
color: #f56c6c;
|
}
|
|
.main-analysis {
|
margin-bottom: 20px;
|
}
|
|
.analysis-card {
|
margin-bottom: 20px;
|
}
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
font-weight: 600;
|
font-size: 16px;
|
}
|
|
.header-controls {
|
display: flex;
|
gap: 10px;
|
}
|
|
.chart-container {
|
padding: 10px 0;
|
}
|
|
.chart {
|
width: 100%;
|
}
|
|
.customer-analysis h4 {
|
margin: 0 0 15px 0;
|
color: #303133;
|
font-size: 14px;
|
}
|
|
.customer-type-distribution {
|
margin-bottom: 20px;
|
}
|
|
.preference-item {
|
display: flex;
|
align-items: center;
|
margin-bottom: 12px;
|
}
|
|
.preference-label {
|
width: 80px;
|
font-size: 12px;
|
color: #606266;
|
}
|
|
.preference-bar {
|
flex: 1;
|
height: 8px;
|
background-color: #f0f0f0;
|
border-radius: 4px;
|
margin: 0 10px;
|
overflow: hidden;
|
}
|
|
.bar-fill {
|
height: 100%;
|
background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
|
border-radius: 4px;
|
transition: width 0.3s ease;
|
}
|
|
.preference-value {
|
width: 40px;
|
font-size: 12px;
|
color: #409eff;
|
font-weight: 500;
|
}
|
|
.detail-analysis {
|
margin-bottom: 20px;
|
}
|
|
.smart-recommendations {
|
margin-bottom: 20px;
|
}
|
|
.recommendations-content {
|
padding: 10px 0;
|
}
|
|
.recommendation-section h4 {
|
margin: 0 0 15px 0;
|
color: #303133;
|
font-size: 14px;
|
border-bottom: 2px solid #409eff;
|
padding-bottom: 5px;
|
}
|
|
.suggestion-item {
|
background: #f8f9fa;
|
border-radius: 6px;
|
padding: 12px;
|
margin-bottom: 12px;
|
border-left: 4px solid #409eff;
|
}
|
|
.suggestion-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 8px;
|
}
|
|
.customer-name {
|
font-weight: 500;
|
color: #303133;
|
}
|
|
.suggestion-content p {
|
margin: 5px 0;
|
font-size: 12px;
|
color: #606266;
|
}
|
|
.coal-type-item {
|
background: #f8f9fa;
|
border-radius: 6px;
|
padding: 12px;
|
margin-bottom: 12px;
|
border-left: 4px solid #67c23a;
|
}
|
|
.coal-info {
|
margin-bottom: 8px;
|
}
|
|
.coal-name {
|
font-weight: 500;
|
color: #303133;
|
font-size: 14px;
|
}
|
|
.coal-spec {
|
font-size: 12px;
|
color: #909399;
|
}
|
|
.coal-metrics {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.metric {
|
font-size: 12px;
|
}
|
|
.metric .label {
|
color: #909399;
|
}
|
|
.metric .value {
|
color: #409eff;
|
font-weight: 500;
|
}
|
|
.improvement-item {
|
background: #f8f9fa;
|
border-radius: 6px;
|
padding: 12px;
|
margin-bottom: 12px;
|
border-left: 4px solid #e6a23c;
|
}
|
|
.improvement-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 8px;
|
}
|
|
.strategy-name {
|
font-weight: 500;
|
color: #303133;
|
}
|
|
.success-rate {
|
font-size: 12px;
|
color: #67c23a;
|
font-weight: 500;
|
}
|
|
.improvement-content p {
|
margin: 5px 0 10px 0;
|
font-size: 12px;
|
color: #606266;
|
}
|
|
.action-buttons {
|
display: flex;
|
gap: 8px;
|
}
|
|
/* 响应式设计 */
|
@media (max-width: 1200px) {
|
.header-controls {
|
flex-direction: column;
|
gap: 5px;
|
}
|
|
.header-controls .el-select {
|
width: 100px !important;
|
}
|
}
|
|
@media (max-width: 768px) {
|
.page-header {
|
flex-direction: column;
|
gap: 15px;
|
text-align: center;
|
}
|
|
.header-info {
|
flex-direction: column;
|
gap: 10px;
|
}
|
}
|
</style>
|