| | |
| | | <div class="app-container indicator-stats"> |
| | | <!-- KPI 汇总 --> |
| | | <el-row :gutter="20" class="stats-row"> |
| | | <el-col :xs="24" :sm="12" :md="8"> |
| | | <el-col :xs="24" :sm="12" :md="6"> |
| | | <div class="stat-card stat-card-blue"> |
| | | <div class="stat-icon-wrapper"> |
| | | <div class="stat-icon"> |
| | |
| | | <div class="stat-bg-decoration"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="8"> |
| | | <el-col :xs="24" :sm="12" :md="6"> |
| | | <div class="stat-card stat-card-green"> |
| | | <div class="stat-icon-wrapper"> |
| | | <div class="stat-icon"> |
| | |
| | | <div class="stat-bg-decoration"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="8"> |
| | | <el-col :xs="24" :sm="12" :md="6"> |
| | | <div class="stat-card stat-card-purple"> |
| | | <div class="stat-icon-wrapper"> |
| | | <div class="stat-icon"> |
| | | <el-icon :size="32"><Goods /></el-icon> |
| | | </div> |
| | | </div> |
| | | <div class="stat-content"> |
| | | <div class="stat-value">{{ formatQuantity(indicatorKpis.productSalesQuantity) }}</div> |
| | | <div class="stat-label">产品销售数量</div> |
| | | </div> |
| | | <div class="stat-bg-decoration"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="6"> |
| | | <div class="stat-card stat-card-orange"> |
| | | <div class="stat-icon-wrapper"> |
| | | <div class="stat-icon"> |
| | |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue' |
| | | import { Document, Van, Tickets, Search, Refresh } from '@element-plus/icons-vue' |
| | | import { Document, Van, Tickets, Search, Refresh, Goods } from '@element-plus/icons-vue' |
| | | import * as echarts from 'echarts' |
| | | import { getTotalStatistics, getStatisticsTable } from '@/api/salesManagement/indicatorStats' |
| | | import { productTreeList } from '@/api/basicData/product.js' |
| | |
| | | const indicatorKpis = reactive({ |
| | | orderCount: 0, |
| | | salesAmount: 0, |
| | | productSalesQuantity: 0, |
| | | shipRate: 0 |
| | | }) |
| | | |
| | |
| | | const productOptions = ref([]) |
| | | const customerOption = ref([]) |
| | | |
| | | const formatQuantity = (value) => { |
| | | const num = Number(value) |
| | | if (Number.isNaN(num)) return '0' |
| | | return num.toLocaleString(undefined, { maximumFractionDigits: 2 }) |
| | | } |
| | | // 转换产品树数据,将 id 改为 value |
| | | function convertIdToValue(data) { |
| | | return data.map((item) => { |
| | |
| | | if (res && res.data) { |
| | | indicatorKpis.orderCount = res.data.total || 0 |
| | | indicatorKpis.salesAmount = res.data.contractAmountTotal || 0 |
| | | // 发货率如果接口没有返回,保持原值或设为0 |
| | | indicatorKpis.productSalesQuantity = res.data.productQuantityTotal || 0 |
| | | indicatorKpis.shipRate = res.data.shipRate || 0 |
| | | } |
| | | } catch (error) { |
| | |
| | | if (indicatorChart) indicatorChart.dispose() |
| | | indicatorChart = echarts.init(indicatorChartRef.value) |
| | | |
| | | // 根据接口返回的数据结构更新图表 |
| | | // 接口返回: dateList, orderCountList, salesAmountList |
| | | // 接口返回: dateList, orderCountList, salesAmountList, productQuantityList |
| | | const option = { |
| | | title: { text: '多维度销售指标趋势', left: 'center' }, |
| | | tooltip: { trigger: 'axis' }, |
| | | legend: { data: ['订单数', '销售额'], top: 30 }, |
| | | legend: { data: ['订单数', '销售额', '产品销售数量'], top: 30 }, |
| | | grid: { left: '3%', right: '8%', bottom: '3%', containLabel: true }, |
| | | xAxis: { |
| | | type: 'category', |
| | |
| | | yAxisIndex: 0, |
| | | data: chartData.salesAmountList || [], |
| | | itemStyle: { color: '#67c23a' } |
| | | }, |
| | | { |
| | | name: '产品销售数量', |
| | | type: 'line', |
| | | yAxisIndex: 1, |
| | | data: chartData.productQuantityList || [], |
| | | itemStyle: { color: '#f56c6c' } |
| | | } |
| | | ] |
| | | } |
| | |
| | | const option = { |
| | | title: { text: '多维度销售指标趋势', left: 'center' }, |
| | | tooltip: { trigger: 'axis' }, |
| | | legend: { data: ['订单数', '销售额'], top: 30 }, |
| | | legend: { data: ['订单数', '销售额', '产品销售数量'], top: 30 }, |
| | | grid: { left: '3%', right: '8%', bottom: '3%', containLabel: true }, |
| | | xAxis: { type: 'category', data: [] }, |
| | | yAxis: [ |
| | |
| | | ], |
| | | series: [ |
| | | { name: '订单数', type: 'line', yAxisIndex: 1, data: [], itemStyle: { color: '#409eff' } }, |
| | | { name: '销售额', type: 'bar', yAxisIndex: 0, data: [], itemStyle: { color: '#67c23a' } } |
| | | { name: '销售额', type: 'bar', yAxisIndex: 0, data: [], itemStyle: { color: '#67c23a' } }, |
| | | { name: '产品销售数量', type: 'line', yAxisIndex: 1, data: [], itemStyle: { color: '#f56c6c' } } |
| | | ] |
| | | } |
| | | indicatorChart.setOption(option) |
| | |
| | | background: #e6a23c; |
| | | } |
| | | } |
| | | |
| | | &.stat-card-purple { |
| | | .stat-icon { |
| | | background: linear-gradient(135deg, #9b59b6 0%, #b37fcc 100%); |
| | | color: #fff; |
| | | } |
| | | |
| | | .stat-bg-decoration { |
| | | background: #9b59b6; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart-card, |