Files
klp-oa/klp-ui/src/views/wms/order/components/CustomerCluster.vue
2025-07-22 15:30:55 +08:00

106 lines
2.3 KiB
Vue

<template>
<div class="customer-cluster">
<el-card shadow="hover">
<div class="chart-title">客户群体聚类分析</div>
<div ref="chart" class="chart-container"></div>
</el-card>
</div>
</template>
<script>
import * as echarts from 'echarts'
export default {
name: 'CustomerCluster',
props: {
customerCluster: {
type: Array,
required: true,
default: () => []
}
},
data () {
return {
chartInstance: null,
chartOptions: {
tooltip: {
trigger: 'item',
formatter: (params) => {
return `客户名称: ${params.data[2]}<br />购买频次: ${params.data[0]}<br />客单价: ${params.data[1]}`
}
},
xAxis: { name: '购买频次' },
yAxis: { name: '客单价' },
series: [
{
symbolSize: 10,
type: 'scatter',
data: []
}
]
}
}
},
watch: {
customerCluster: {
immediate: true,
handler(newVal) {
this.updateChart()
}
}
},
mounted () {
this.initChart()
},
beforeDestroy () {
if (this.chartInstance) {
this.chartInstance.dispose()
}
window.removeEventListener('resize', this.handleResize)
},
methods: {
initChart () {
const chartDom = this.$refs.chart
if (!chartDom) return
this.chartInstance = echarts.init(chartDom)
this.updateChart()
window.addEventListener('resize', this.handleResize)
},
updateChart () {
if (!this.chartInstance) return
// 格式化数据
const chartData = this.customerCluster.map(item => [item.purchaseFreq, item.avgOrderAmount, item.customerName])
this.chartOptions.series[0].data = chartData
this.chartInstance.setOption(this.chartOptions)
},
handleResize () {
if (this.chartInstance) {
this.chartInstance.resize()
}
}
}
}
</script>
<style scoped>
.customer-cluster {
width: 100%;
height: 100%;
}
.chart-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 8px;
}
.chart-container {
width: 100%;
height: 400px;
}
.el-card {
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
padding: 16px;
display: flex;
flex-direction: column;
}
</style>