修改移动端内容,后端添加了所有查询接口

This commit is contained in:
2025-10-31 17:18:30 +08:00
parent 9800a37055
commit ac541472c2
9 changed files with 2530 additions and 1262 deletions

View File

@@ -1,147 +1,141 @@
<template>
<view class="container">
<!-- 日月年汇总单选 -->
<view class="tab-container">
<view
v-for="item in timeTabs"
<view class="page-container">
<!-- 时间维度切换 -->
<view class="time-tab-bar">
<view
v-for="item in timeTabs"
:key="item.value"
class="tab-item"
:class="{ active: activeTab === item.value }"
class="time-tab-item"
:class="{ 'time-tab-active': activeTab === item.value }"
@click="handleTabChange(item.value)"
>
{{ item.label }}
</view>
</view>
<!-- 日期选择 -->
<view class="date-picker">
<!-- 日期选择 -->
<view class="date-selector">
<!-- 日模式 -->
<view v-if="activeTab === 'day'" class="date-item">
<picker
mode="date"
:value="startDate"
@change="handleDateChange"
>
<view class="picker-text">选择日期{{ startDate }}</view>
<picker v-if="activeTab === 'day'" mode="date" :value="startDate" @change="handleDateChange">
<view class="date-input">
<text class="date-label">日期</text>
<text class="date-value">{{ startDate }}</text>
</view>
</picker>
<!-- 月模式 -->
<view v-else-if="activeTab === 'month'" class="date-range-group">
<picker mode="date" fields="month" :value="startDate" @change="handleStartMonthChange">
<view class="date-input">
<text class="date-label"></text>
<text class="date-value">{{ startDate }}</text>
</view>
</picker>
<view class="date-separator"></view>
<picker mode="date" fields="month" :value="endDate" :start="startDate" :end="maxMonthEnd" @change="handleEndMonthChange">
<view class="date-input">
<text class="date-label"></text>
<text class="date-value">{{ endDate }}</text>
</view>
</picker>
</view>
<!-- 月模式 -->
<view v-else-if="activeTab === 'month'" class="date-range">
<view class="date-item">
<picker
mode="date"
fields="month"
:value="startDate"
@change="handleStartMonthChange"
>
<view class="picker-text">开始月份{{ startDate }}</view>
</picker>
</view>
<view class="date-item">
<picker
mode="date"
fields="month"
:value="endDate"
:start="startDate"
:end="maxMonthEnd"
@change="handleEndMonthChange"
>
<view class="picker-text">结束月份{{ endDate }}</view>
</picker>
</view>
</view>
<!-- 年模式 -->
<view v-else class="date-range">
<view class="date-item">
<picker
mode="date"
fields="year"
:value="startDate"
@change="handleStartYearChange"
>
<view class="picker-text">开始年份{{ startDate }}</view>
<view v-else class="date-range-group">
<picker mode="date" fields="year" :value="startDate" @change="handleStartYearChange">
<view class="date-input">
<text class="date-label"></text>
<text class="date-value">{{ startDate }}</text>
</view>
</picker>
<view class="date-separator"></view>
<picker mode="date" fields="year" :value="endDate" @change="handleEndYearChange">
<view class="date-input">
<text class="date-label"></text>
<text class="date-value">{{ endDate }}</text>
</view>
</picker>
</view>
<view class="date-item">
<picker
mode="date"
fields="year"
:value="endDate"
@change="handleEndYearChange"
>
<view class="picker-text">结束年份{{ endDate }}</view>
</picker>
</view>
<!-- 生产汇总数据 -->
<view class="summary-section">
<view class="section-header">
<text class="section-title">生产汇总</text>
<text class="section-date">{{ displayDateRange }}</text>
</view>
<view class="summary-grid">
<view class="summary-card" v-for="(item, index) in summaryData" :key="index">
<text class="summary-label">{{ item.label }}</text>
<view class="summary-value-box">
<text class="summary-value">{{ item.value }}</text>
<text v-if="item.unit" class="summary-unit">{{ item.unit }}</text>
</view>
</view>
</view>
</view>
<!-- 统计图轮播产量相关 -->
<view class="chart-container">
<swiper
class="chart-swiper"
:current="currentSwiperIndex"
@change="onSwiperChange"
:autoplay="false"
:circular="false"
:indicator-dots="true"
indicator-active-color="#1a73e8"
indicator-color="#e5e5e5"
>
<swiper-item v-for="(item, index) in chanLiangChartConfig" :key="index">
<qiun-data-charts :type="item.type" :chartData="item.chartData" :title="item.title"/>
</swiper-item>
</swiper>
<!-- 产量趋势图 -->
<view class="chart-section">
<view class="section-header">
<text class="section-title">产量趋势</text>
</view>
<view class="chart-wrapper">
<qiun-data-charts type="mix" :chartData="productionChartData" :opts="productionChartOpts"/>
</view>
</view>
<!-- 日期范围汇总 -->
<klp-collapse-panel :title="'汇总(' + displayDateRange + ''">
<k-metric-card
:items="summaryData"
:columns="3"
/>
<!-- 班组产量对比 -->
<view class="chart-section">
<view class="section-header">
<text class="section-title">班组产量对比</text>
</view>
<view class="chart-wrapper">
<qiun-data-charts type="column" :chartData="crewChartData" :opts="columnChartOpts"/>
</view>
</view>
<!-- 汇总饼图轮播 -->
<swiper
class="chart-swiper"
:autoplay="false"
:circular="false"
:indicator-dots="true"
indicator-active-color="#1a73e8"
indicator-color="#e5e5e5"
>
<swiper-item v-for="(item, index) in summaryChartConfig" :key="index">
<qiun-data-charts type="pie" :opts="item.opts" :chartData="item.chartData" :title="item.title"/>
</swiper-item>
</swiper>
</klp-collapse-panel>
<!-- 规格分布 -->
<view class="chart-section">
<view class="section-header">
<text class="section-title">规格分布</text>
</view>
<view class="pie-charts-row">
<view class="pie-chart-item">
<text class="pie-title">厚度分布</text>
<qiun-data-charts type="pie" :chartData="thicknessPieData" :opts="pieChartOpts"/>
</view>
</view>
<view class="pie-charts-row">
<view class="pie-chart-item">
<text class="pie-title">宽度分布</text>
<qiun-data-charts type="pie" :chartData="widthPieData" :opts="pieChartOpts"/>
</view>
</view>
</view>
</view>
</template>
<script>
// 2. 独立工具函数避免Vue2 data初始化时调用this.methods的问题
/**
* 获取默认日期(根据视图类型)
* @param {string} type - 视图类型day/month/year
* @returns {string} 格式化后的日期
*/
import {
getProductionSummary,
getCrewProduction,
getThicknessDistribution,
getWidthDistribution
} from '@/api/pocket/plantState'
// 工具函数
function getDefaultDate(type = "day") {
const date = new Date();
return formatDate(date, type);
}
/**
* 格式化日期
* @param {Date} date - 日期对象
* @param {string} type - 视图类型day/month/year
* @returns {string} 格式化后的日期
*/
function formatDate(date, type) {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
switch (type) {
case "day": return `${year}-${month}-${day}`;
case "month": return `${year}-${month}`;
@@ -151,128 +145,97 @@ function formatDate(date, type) {
}
export default {
// 4. 响应式数据(替代 Vue3 的 ref
data() {
return {
// 激活的视图类型(日/月/年)
activeTab: "day",
// 开始/结束日期(月份/年份)
startDate: getDefaultDate(),
endDate: getDefaultDate(),
// 视图切换选项
timeTabs: [
{ label: "日视图", value: "day" },
{ label: "月视图", value: "month" },
{ label: "年视图", value: "year" }
{ label: "日", value: "day" },
{ label: "月", value: "month" },
{ label: "年", value: "year" }
],
// 产量相关图表配置(轮播)
chanLiangChartConfig: [
{
title: "规格曲线",
type: "column",
chartData: {} // 初始空对象,后续加载数据
},
{
title: "超产-欠产统计",
type: "line",
chartData: {} // 初始空对象,后续加载数据
},
{
title: "产量-成材率统计",
type: "column",
chartData: {
categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
series: [
{ name: "目标值", data: [35, 36, 31, 33, 13, 34] },
{ name: "完成量", data: [18, 27, 21, 24, 6, 28] }
]
} // 固定初始数据
}
],
// 汇总饼图配置(轮播)
summaryChartConfig: [
{
title: "成品厚度统计(mm)",
opts: {
color: ["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
padding: [5,5,5,5],
enableScroll: false,
position: "left",
float: "left",
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
offsetAngle: 0,
labelWidth: 15,
border: false,
borderWidth: 3,
borderColor: "#FFFFFF"
}
}
},
chartData: JSON.parse(JSON.stringify({
series: [{ data: [{"name":"一班","value":50},{"name":"二班","value":30},{"name":"三班","value":20},{"name":"四班","value":18},{"name":"五班","value":8}] }]
}))
},
{
title: "钢种统计",
opts: {
color: ["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
padding: [5,5,5,5],
enableScroll: false,
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
offsetAngle: 0,
labelWidth: 15,
border: false,
borderWidth: 3,
borderColor: "#FFFFFF"
}
}
},
chartData: JSON.parse(JSON.stringify({
series: [{ data: [{"name":"一班","value":50},{"name":"二班","value":30},{"name":"三班","value":20},{"name":"四班","value":18},{"name":"五班","value":8}] }]
}))
},
{
title: "班组统计",
opts: {
color: ["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
padding: [5,5,5,5],
enableScroll: false,
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
offsetAngle: 0,
labelWidth: 15,
border: false,
borderWidth: 3,
borderColor: "#FFFFFF"
}
}
},
chartData: JSON.parse(JSON.stringify({
series: [{ data: [{"name":"一班","value":50},{"name":"二班","value":30},{"name":"三班","value":20},{"name":"四班","value":18},{"name":"五班","value":8}] }]
}))
}
],
// 轮播图当前索引
currentSwiperIndex: 0,
// 服务器加载的图表基础数据
chartData: {},
// 汇总指标卡数据
// 汇总数据
summaryData: [
{ label: "生产钢卷数", value: 186 },
{ label: "平均宽度", value: 1054, unit: "mm" },
{ label: "平均厚度", value: 0.93, unit: "mm" },
{ label: "原料总量", value: 3396.47, unit: "t" },
{ label: "成品总量", value: 4360.18, unit: "t" },
{ label: "成材率", value: 95.99, unit: "%" } // 原代码unit写t推测是笔误修正为%
]
{ label: "生产钢卷数", value: 0, unit: "卷" },
{ label: "平均宽度", value: 0, unit: "mm" },
{ label: "平均厚度", value: 0, unit: "mm" },
{ label: "原料总量", value: 0, unit: "t" },
{ label: "成品总量", value: 0, unit: "t" },
{ label: "成材率", value: 0, unit: "%" }
],
// 产量趋势图(柱状+折线)
productionChartData: {},
productionChartOpts: {
color: ["#0066cc", "#00b96b"],
padding: [15, 15, 0, 15],
enableScroll: false,
legend: { position: "top" },
xAxis: { disableGrid: true },
yAxis: {
gridType: "dash",
dashLength: 4,
gridColor: "#e4e7ed",
data: [
{ position: "left", title: "产量(t)" },
{ position: "right", title: "成材率(%)" }
]
},
extra: {
mix: {
column: { width: 20 }
}
}
},
// 班组产量对比
crewChartData: {},
columnChartOpts: {
color: ["#0066cc", "#409eff", "#66b1ff"],
padding: [15, 15, 0, 15],
enableScroll: false,
legend: {},
xAxis: { disableGrid: true },
yAxis: {
gridType: "dash",
dashLength: 4,
gridColor: "#e4e7ed",
data: [{ title: "产量(t)" }]
}
},
// 饼图配置
pieChartOpts: {
color: ["#0066cc", "#409eff", "#66b1ff", "#a0cfff", "#d9ecff"],
padding: [15, 15, 15, 15],
enableScroll: false,
legend: {
show: true,
position: "bottom",
lineHeight: 16,
fontSize: 10,
fontColor: "#666",
margin: 5,
itemGap: 8
},
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
labelWidth: 15,
border: false,
ringWidth: 0,
offsetAngle: 0,
disablePieStroke: true,
linearType: "none",
customRadius: 0
}
}
},
thicknessPieData: {
series: [{ data: [] }]
},
widthPieData: {
series: [{ data: [] }]
}
};
},
// 5. 计算属性(替代 Vue3 的 computed 函数)
@@ -298,168 +261,427 @@ export default {
}
}
},
// 6. 生命周期钩子(替代 Vue3 的 onMounted
mounted() {
this.getServerData(); // 页面挂载后加载图表数据
this.loadProductionData();
},
// 7. 方法定义(所有交互逻辑与数据处理)
methods: {
// 切换视图(日/月/年)
// 切换时间维度
handleTabChange(tab) {
this.activeTab = tab;
// 重置日期:日视图首尾一致,月/年视图首尾默认当前
const defaultDate = getDefaultDate();
this.startDate = defaultDate;
this.endDate = tab === "day" ? defaultDate : getDefaultDate(tab);
this.loadProductionData();
},
// 日模式:日期选择器变更
// 日期选择变更
handleDateChange(e) {
this.startDate = e.detail.value;
this.endDate = e.detail.value; // 日视图首尾日期同步
this.endDate = e.detail.value;
this.loadProductionData();
},
// 月模式:开始月份变更
handleStartMonthChange(e) {
this.startDate = e.detail.value;
// 自动调整结束月份:不超过开始月份+1年
const maxEndDate = new Date(this.startDate);
maxEndDate.setFullYear(maxEndDate.getFullYear() + 1);
const maxEndStr = formatDate(maxEndDate, "month");
if (new Date(this.endDate) > maxEndDate) {
this.endDate = maxEndStr;
}
this.loadProductionData();
},
// 月模式:结束月份变更
handleEndMonthChange(e) {
this.endDate = e.detail.value;
this.loadProductionData();
},
// 年模式:开始年份变更
handleStartYearChange(e) {
this.startDate = e.detail.value;
this.loadProductionData();
},
// 年模式:结束年份变更
handleEndYearChange(e) {
this.endDate = e.detail.value;
this.loadProductionData();
},
// 轮播图切换回调(更新当前索引)
onSwiperChange(e) {
this.currentSwiperIndex = e.detail.current;
// 加载生产数据
loadProductionData() {
uni.showLoading({ title: '加载中' })
// 并行请求所有数据
Promise.all([
this.loadSummaryData(),
this.loadCrewProductionData(),
this.loadSpecDistribution()
]).finally(() => {
uni.hideLoading()
})
},
// 模拟从服务器加载图表数据
getServerData() {
setTimeout(() => {
// 模拟服务器返回数据
const serverRes = {
categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
series: [
{ name: "目标值", data: [35, 36, 31, 33, 13, 34] },
{ name: "完成量", data: [18, 27, 21, 24, 6, 28] }
// 加载汇总数据
loadSummaryData() {
// 转换为完整日期格式
const start = this.formatFullDate(this.startDate, true)
const end = this.formatFullDate(this.endDate, false)
return getProductionSummary(start, end).then(response => {
if (response.code === 200 && response.data) {
const data = response.data
this.summaryData = [
{ label: "生产钢卷数", value: data.coilCount || 0, unit: "卷" },
{ label: "平均宽度", value: data.avgWidth || 0, unit: "mm" },
{ label: "平均厚度", value: data.avgThick || 0, unit: "mm" },
{ label: "原料总量", value: data.totalEntryWeight || 0, unit: "t" },
{ label: "成品总量", value: data.totalExitWeight || 0, unit: "t" },
{ label: "成材率", value: data.yieldRate || 0, unit: "%" }
]
};
// 深拷贝避免引用问题确保Vue2响应式
this.chartData = JSON.parse(JSON.stringify(serverRes));
// 更新产量图表配置的前两个图表数据(第三个固定)
this.chanLiangChartConfig.forEach((item, index) => {
if (index < 2) { // 仅前两个图表用服务器数据
item.chartData = JSON.parse(JSON.stringify(this.chartData));
}
}).catch(error => {
console.error('加载汇总数据失败:', error)
})
},
// 加载班组产量数据
loadCrewProductionData() {
const start = this.formatFullDate(this.startDate, true)
const end = this.formatFullDate(this.endDate, false)
return getCrewProduction(start, end).then(response => {
if (response.code === 200 && response.data && response.data.length > 0) {
const crewData = response.data
// 按班组和班次分组
const categories = []
const crewMap = {}
crewData.forEach(item => {
const label = `${item.crew}-${item.shift}`
categories.push(label)
if (!crewMap[item.shift]) {
crewMap[item.shift] = []
}
crewMap[item.shift].push(Number(item.totalWeight) || 0)
})
// 构建班组产量对比图
const series = Object.keys(crewMap).map(shift => ({
name: shift,
data: crewMap[shift]
}))
this.crewChartData = {
categories: categories,
series: series
}
});
}, 500);
// 构建产量趋势图(使用班组数据)
this.productionChartData = {
categories: categories,
series: [
{
name: "产量",
type: "column",
index: 0,
data: crewData.map(item => Number(item.totalWeight) || 0)
},
{
name: "平均厚度",
type: "line",
index: 1,
style: "curve",
data: crewData.map(item => Number(item.avgThick) || 0)
}
]
}
}
}).catch(error => {
console.error('加载班组产量失败:', error)
})
},
// 加载规格分布
loadSpecDistribution() {
const start = this.formatFullDate(this.startDate, true)
const end = this.formatFullDate(this.endDate, false)
return Promise.all([
getThicknessDistribution(start, end),
getWidthDistribution(start, end)
]).then(([thicknessRes, widthRes]) => {
// 厚度分布
if (thicknessRes.code === 200 && thicknessRes.data) {
this.thicknessPieData = {
series: [{
data: thicknessRes.data.map(item => ({
name: item.category,
value: item.count
}))
}]
}
}
// 宽度分布
if (widthRes.code === 200 && widthRes.data) {
this.widthPieData = {
series: [{
data: widthRes.data.map(item => ({
name: item.category,
value: item.count
}))
}]
}
}
}).catch(error => {
console.error('加载规格分布失败:', error)
})
},
// 格式化为完整日期(用于查询)
formatFullDate(dateStr, isStart) {
if (!dateStr) return ''
// 如果已经是完整日期格式 yyyy-MM-dd直接返回
if (dateStr.length === 10) {
return dateStr
}
// 月份格式 yyyy-MM
if (dateStr.length === 7) {
if (isStart) {
// 开始日期:该月第一天
return `${dateStr}-01`
} else {
// 结束日期:该月最后一天
const [year, month] = dateStr.split('-')
const lastDay = new Date(year, month, 0).getDate()
return `${dateStr}-${String(lastDay).padStart(2, '0')}`
}
}
// 年份格式 yyyy
if (dateStr.length === 4) {
if (isStart) {
// 开始日期:该年第一天
return `${dateStr}-01-01`
} else {
// 结束日期:该年最后一天
return `${dateStr}-12-31`
}
}
return dateStr
}
}
};
</script>
<style scoped>
.container {
padding: 20rpx;
<style scoped lang="scss">
/* 页面容器 */
.page-container {
background: #f5f7fa;
padding: 24rpx;
}
/* 简洁Tab容器 */
.tab-container {
/* 时间维度切换 */
.time-tab-bar {
display: flex;
box-sizing: border-box;
background: #fff;
margin-bottom: 20rpx;
border-radius: 12rpx;
overflow: hidden;
border: 1rpx solid #e8e8e8;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
border-radius: 8rpx;
padding: 8rpx;
margin-bottom: 24rpx;
border: 1rpx solid #e4e7ed;
}
.tab-item {
.time-tab-item {
flex: 1;
text-align: center;
padding: 24rpx 20rpx;
color: #666;
font-size: 28rpx;
font-weight: 500;
transition: all 0.3s ease;
position: relative;
&:not(:last-child)::after {
content: '';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 1rpx;
height: 40rpx;
background: #e8e8e8;
}
padding: 16rpx 0;
font-size: 26rpx;
color: #606266;
border-radius: 6rpx;
transition: all 0.2s;
}
.tab-item.active {
.time-tab-active {
background: #0066cc;
color: #fff;
background: #1a73e8;
font-weight: 600;
font-weight: 500;
}
/* 日期选择 */
.date-picker {
padding: 20rpx;
/* 日期选择 */
.date-selector {
background: #fff;
border-radius: 12rpx;
margin-bottom: 20rpx;
border: 1rpx solid #e8e8e8;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
border-radius: 8rpx;
padding: 24rpx;
margin-bottom: 24rpx;
border: 1rpx solid #e4e7ed;
}
.date-range {
.date-range-group {
display: flex;
gap: 20rpx;
align-items: stretch;
gap: 0;
}
.date-item {
.date-input {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
background: #f5f7fa;
border: 1rpx solid #e4e7ed;
&:first-child {
border-radius: 6rpx 0 0 6rpx;
border-right: none;
}
&:last-child {
border-radius: 0 6rpx 6rpx 0;
border-left: none;
}
}
.picker-text {
padding: 20rpx;
background: #f8f9fa;
border-radius: 10rpx;
color: #333;
.date-label {
font-size: 26rpx;
color: #909399;
margin-right: 16rpx;
}
.date-value {
font-size: 28rpx;
border: 1rpx solid #e8e8e8;
transition: all 0.2s ease;
&:active {
background: #f0f2f5;
}
color: #303133;
font-weight: 500;
flex: 1;
text-align: right;
}
.date-separator {
font-size: 28rpx;
color: #fff;
background: #0066cc;
padding: 24rpx 20rpx;
display: flex;
align-items: center;
justify-content: center;
min-width: 80rpx;
}
/* 区块样式 */
.summary-section,
.chart-section {
margin-bottom: 24rpx;
}
.section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
padding-left: 16rpx;
border-left: 4rpx solid #0066cc;
}
.section-title {
font-size: 30rpx;
font-weight: 500;
color: #303133;
}
.section-date {
font-size: 24rpx;
color: #909399;
}
/* 汇总卡片网格 */
.summary-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16rpx;
}
.summary-card {
background: #fff;
border: 1rpx solid #e4e7ed;
border-radius: 8rpx;
padding: 28rpx 20rpx;
text-align: center;
}
.summary-label {
display: block;
font-size: 24rpx;
color: #909399;
margin-bottom: 16rpx;
}
.summary-value-box {
display: flex;
align-items: baseline;
justify-content: center;
}
.summary-value {
font-size: 40rpx;
font-weight: 600;
color: #0066cc;
line-height: 1;
}
.summary-unit {
font-size: 22rpx;
color: #909399;
margin-left: 6rpx;
}
/* 图表容器 */
.chart-container {
margin-bottom: 20rpx;
.chart-wrapper {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
border: 1rpx solid #e8e8e8;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
border: 1rpx solid #e4e7ed;
border-radius: 8rpx;
padding: 24rpx 16rpx;
min-height: 450rpx;
}
.chart-swiper {
height: 500rpx;
box-sizing: border-box;
/* 饼图行布局 */
.pie-charts-row {
display: flex;
gap: 16rpx;
}
</style>
.pie-chart-item {
flex: 1;
background: #fff;
border: 1rpx solid #e4e7ed;
border-radius: 8rpx;
padding: 24rpx 0 32rpx 0;
min-height: 520rpx;
display: flex;
flex-direction: column;
}
.pie-title {
display: block;
text-align: center;
font-size: 26rpx;
color: #606266;
font-weight: 500;
margin-bottom: 16rpx;
padding: 0 16rpx;
flex-shrink: 0;
}
.pie-chart-wrapper {
flex: 1;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>