Files
GEAR-OA/gear-ui3/src/views/dashboard/grid/index.vue
2025-09-05 14:47:32 +08:00

254 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 图表容器含滚动 -->
<div class="charts-container">
<!-- Element 布局行容器不变 -->
<el-row class="charts-row" :gutter="20" :style="{ height: `calc(100% - 40px)` }">
<!-- 动态渲染图表应用高度配置核心修改 -->
<el-col v-for="(chartConfig, index) in persistedChartConfigs" :key="chartConfig.id" class="chart-col"
:xs="chartConfig.layout.xs" :sm="chartConfig.layout.sm" :md="chartConfig.layout.md" :lg="chartConfig.layout.lg"
:xl="chartConfig.layout.xl" :style="{ height: `${chartConfig.height || 400}px`, marginBottom: '20px' }">
<!-- 动态加载图表组件确保组件高度100% -->
<component :is="chartComponentMap[chartConfig.componentName]" class="chart-item"
v-bind="getChartProps(chartConfig)" :is-refreshing="isRefreshing" :chart-height="chartConfig.height || 400" />
</el-col>
</el-row>
</div>
</template>
<script setup>
import { useStorage } from '@vueuse/core';
import { ElRow, ElCol } from 'element-plus';
// 1. 导入所有图表子组件(不变)
import OrderTrendChart from '../components/OrderTrendChart.vue';
import ProductSalesRank from '../components/ProductSalesRank.vue';
import CustomerFollowStatus from '../components/CustomerFollowStatus.vue';
import ReturnExchangeAnalysis from '../components/ReturnExchangeAnalysis.vue';
import SalesByManagerChart from '../components/SalesByManagerChart.vue';
import SalesByCustomerChart from '../components/SalesByCustomerChart.vue';
import SalesMetricsCard from '../components/SalesMetricsCard.vue';
import RecentOrdersTable from '../components/RecentOrdersTable.vue';
// 2. 图表组件映射表(不变)
const chartComponentMap = {
OrderTrendChart,
ProductSalesRank,
CustomerFollowStatus,
ReturnExchangeAnalysis,
SalesByManagerChart,
SalesByCustomerChart,
SalesMetricsCard,
RecentOrdersTable
};
// 3. 图表默认配置数组新增height默认值核心修改
const DEFAULT_CHART_CONFIGS = [
{
"id": "product-rank",
"componentName": "ProductSalesRank",
"title": "产品销售排行图表",
"dataKey": "orderDetails",
"layout": {
"xs": 24,
"sm": 24,
"md": 8,
"lg": "8",
"xl": 12
},
"height": 400
},
{
"id": "customer-follow",
"componentName": "CustomerFollowStatus",
"title": "客户跟进状态图表",
"dataKey": "customers",
"layout": {
"xs": 24,
"sm": 24,
"md": 8,
"lg": "8",
"xl": 12
},
"height": 400
},
{
"id": "sales-metrics",
"componentName": "SalesMetricsCard",
"title": "销售指标图表",
"dataKey": [
"orders",
"customers",
"returnExchanges"
],
"layout": {
"xs": 24,
"sm": 24,
"md": 8,
"lg": "8",
"xl": 12
},
"height": 200
},
{
"id": "order-trend",
"componentName": "OrderTrendChart",
"title": "订单趋势图表",
"dataKey": "orders",
"layout": {
"xs": 24,
"sm": 24,
"md": 12,
"lg": 12,
"xl": 12
},
"height": 400
},
{
"id": "sales-manager",
"componentName": "SalesByManagerChart",
"title": "负责人订单汇总",
"dataKey": "orders",
"layout": {
"xs": 24,
"sm": 24,
"md": 12,
"lg": 12,
"xl": 12
},
"height": 400
},
{
"id": "return-exchange",
"componentName": "ReturnExchangeAnalysis",
"title": "退换货分析图表",
"dataKey": "returnExchanges",
"layout": {
"xs": 24,
"sm": 24,
"md": 12,
"lg": 12,
"xl": 12
},
"height": 400
},
{
"id": "sales-customer",
"componentName": "SalesByCustomerChart",
"title": "客户订单汇总",
"dataKey": "orders",
"layout": {
"xs": 24,
"sm": 24,
"md": 12,
"lg": 12,
"xl": 12
},
"height": 400
},
{
"id": "recent-orders",
"componentName": "RecentOrdersTable",
"title": "最近订单",
"dataKey": "orders",
"layout": {
"xs": 24,
"sm": 24,
"md": "24",
"lg": "24",
"xl": "24"
},
"height": 400
}
];
// 4. 持久化图表配置不变但默认值包含height
const persistedChartConfigs = useStorage(
'saleDashboardChartConfigs',
DEFAULT_CHART_CONFIGS,
localStorage,
{ mergeDefaults: true }
);
// 5. 接收父组件传入的数据源与状态(不变)
const props = defineProps({
orders: { type: Array, required: true, default: () => [] },
orderDetails: { type: Array, required: true, default: () => [] },
customers: { type: Array, required: true, default: () => [] },
returnExchanges: { type: Array, required: true, default: () => [] },
isRefreshing: { type: Boolean, required: true, default: false }
});
// 6. 工具函数传递props不变
const getChartProps = (chartConfig) => {
const dataMap = {
orders: props.orders,
orderDetails: props.orderDetails,
customers: props.customers,
returnExchanges: props.returnExchanges
};
if (Array.isArray(chartConfig.dataKey)) {
const o = { title: chartConfig.title };
chartConfig.dataKey.forEach(key => {
o[key.replace(/([A-Z])/g, '-$1').toLowerCase()] = dataMap[key];
});
return o;
}
return {
[chartConfig.dataKey.replace(/([A-Z])/g, '-$1').toLowerCase()]: dataMap[chartConfig.dataKey],
title: chartConfig.title
};
};
</script>
<style scoped>
/* 图表容器(不变) */
.charts-container {
width: 100%;
height: 100%;
padding: 20px;
overflow: auto;
box-sizing: border-box;
background-color: #0f172a;
}
/* 行容器(不变) */
.charts-row {
width: 100%;
margin: 0;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
/* 列容器:移除固定高度,由配置动态控制(核心修改) */
.chart-col {
box-sizing: border-box;
/* 高度由父组件style动态设置此处不固定 */
}
/* 图表项100%高度继承列容器(核心修改) */
.chart-item {
width: 100%;
height: 100%;
/* 关键:让组件填满列容器高度 */
background-color: #1e293b;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
overflow: hidden;
display: flex;
flex-direction: column;
}
/* 小屏幕优化(不变) */
@media (max-width: 768px) {
.charts-container {
padding: 10px;
}
.chart-item {
padding: 12px;
}
}
</style>