feat: 移动式检修车间系统前端完成
- 完成系统日志页面,优化表格滚动和样式 - 完成报警记录页面,优化表格滚动和报警级别显示 - 完成环境参数页面,优化参数显示和监控画面 - 完成参数记录页面,优化图表样式和简洁设计 - 集成MQTT配置,支持实时数据对接 - 统一UI设计风格,采用现代化卡片式布局 - 添加响应式设计,适配不同屏幕尺寸 - 预留MQTT数据接口,支持AC空调和WSD温湿度设备
This commit is contained in:
675
src/components/ParameterRecord.vue
Normal file
675
src/components/ParameterRecord.vue
Normal file
@ -0,0 +1,675 @@
|
||||
<template>
|
||||
<view class="page-container parameter-record-container">
|
||||
<!-- 页面头部 -->
|
||||
<view class="page-header">
|
||||
<view class="header-left">
|
||||
<text class="page-title">参数记录</text>
|
||||
<view class="date-selector" @click="showDatePicker">
|
||||
<text class="date-text">{{ currentDate }}</text>
|
||||
<text class="date-icon">▼</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-right">
|
||||
<view class="system-title">
|
||||
<view class="system-title-icon">
|
||||
<text class="icon">📋</text>
|
||||
</view>
|
||||
<text class="system-title-text">移动式检修车间系统</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 图表区域 -->
|
||||
<view class="page-content">
|
||||
<scroll-view
|
||||
class="charts-scroll-container"
|
||||
scroll-y="true"
|
||||
:scroll-with-animation="true"
|
||||
:scroll-top="scrollTop"
|
||||
@scrolltolower="onScrollToLower"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<view class="charts-container">
|
||||
<!-- 温度图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<view class="chart-info">
|
||||
<text class="chart-title">温度趋势</text>
|
||||
<text class="chart-subtitle">24小时数据</text>
|
||||
</view>
|
||||
<view class="chart-status">
|
||||
<view class="status-dot temperature-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="chart-content">
|
||||
<canvas
|
||||
id="temperatureChart"
|
||||
canvas-id="temperatureChart"
|
||||
class="chart-canvas"
|
||||
@touchstart="onChartTouch"
|
||||
@touchmove="onChartTouch"
|
||||
@touchend="onChartTouch"
|
||||
></canvas>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 湿度图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<view class="chart-info">
|
||||
<text class="chart-title">湿度趋势</text>
|
||||
<text class="chart-subtitle">24小时数据</text>
|
||||
</view>
|
||||
<view class="chart-status">
|
||||
<view class="status-dot humidity-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="chart-content">
|
||||
<canvas
|
||||
id="humidityChart"
|
||||
canvas-id="humidityChart"
|
||||
class="chart-canvas"
|
||||
@touchstart="onChartTouch"
|
||||
@touchmove="onChartTouch"
|
||||
@touchend="onChartTouch"
|
||||
></canvas>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- PM图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<view class="chart-info">
|
||||
<text class="chart-title">PM2.5趋势</text>
|
||||
<text class="chart-subtitle">24小时数据</text>
|
||||
</view>
|
||||
<view class="chart-status">
|
||||
<view class="status-dot pm-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="chart-content">
|
||||
<canvas
|
||||
id="pmChart"
|
||||
canvas-id="pmChart"
|
||||
class="chart-canvas"
|
||||
@touchstart="onChartTouch"
|
||||
@touchmove="onChartTouch"
|
||||
@touchend="onChartTouch"
|
||||
></canvas>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部间距 -->
|
||||
<view class="content-bottom-spacing"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, nextTick } from 'vue';
|
||||
|
||||
// 当前日期
|
||||
const currentDate = ref('2025年9月1日');
|
||||
|
||||
// 滚动相关
|
||||
const scrollTop = ref(0);
|
||||
const isScrolling = ref(false);
|
||||
|
||||
// 模拟数据
|
||||
const temperatureData = ref([]);
|
||||
const humidityData = ref([]);
|
||||
const pmData = ref([]);
|
||||
const pressureData = ref([]);
|
||||
const windSpeedData = ref([]);
|
||||
const lightData = ref([]);
|
||||
|
||||
// MQTT数据请求接口(预留)
|
||||
const mqttService = {
|
||||
// 连接MQTT服务器
|
||||
connect: () => {
|
||||
console.log('MQTT连接中...');
|
||||
// 这里后期会实现真实的MQTT连接
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
// 订阅参数数据
|
||||
subscribeParameterData: (date) => {
|
||||
console.log(`订阅${date}的参数数据`);
|
||||
// 这里后期会实现真实的MQTT订阅
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
// 获取历史数据
|
||||
getHistoricalData: (date, parameter) => {
|
||||
console.log(`获取${date}的${parameter}历史数据`);
|
||||
// 这里后期会实现真实的MQTT数据请求
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
// 断开连接
|
||||
disconnect: () => {
|
||||
console.log('MQTT断开连接');
|
||||
// 这里后期会实现真实的MQTT断开
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
// 清空现有数据
|
||||
temperatureData.value = [];
|
||||
humidityData.value = [];
|
||||
pmData.value = [];
|
||||
pressureData.value = [];
|
||||
windSpeedData.value = [];
|
||||
lightData.value = [];
|
||||
|
||||
// 生成24小时的模拟数据
|
||||
for (let i = 0; i < 24; i++) {
|
||||
temperatureData.value.push({
|
||||
time: i,
|
||||
value: 20 + Math.sin(i * Math.PI / 12) * 5 + Math.random() * 2
|
||||
});
|
||||
|
||||
humidityData.value.push({
|
||||
time: i,
|
||||
value: 50 + Math.sin(i * Math.PI / 8) * 10 + Math.random() * 3
|
||||
});
|
||||
|
||||
pmData.value.push({
|
||||
time: i,
|
||||
value: 30 + Math.sin(i * Math.PI / 6) * 8 + Math.random() * 4
|
||||
});
|
||||
|
||||
pressureData.value.push({
|
||||
time: i,
|
||||
value: 1013 + Math.sin(i * Math.PI / 10) * 5 + Math.random() * 2
|
||||
});
|
||||
|
||||
windSpeedData.value.push({
|
||||
time: i,
|
||||
value: 5 + Math.sin(i * Math.PI / 6) * 3 + Math.random() * 2
|
||||
});
|
||||
|
||||
lightData.value.push({
|
||||
time: i,
|
||||
value: 200 + Math.sin(i * Math.PI / 12) * 100 + Math.random() * 50
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 绘制图表
|
||||
const drawChart = (canvasId, data, color = '#000000') => {
|
||||
const ctx = uni.createCanvasContext(canvasId);
|
||||
// 获取实际canvas尺寸
|
||||
const query = uni.createSelectorQuery();
|
||||
query.select(`#${canvasId}`).boundingClientRect((rect) => {
|
||||
if (rect) {
|
||||
const canvasWidth = rect.width;
|
||||
const canvasHeight = rect.height;
|
||||
drawChartContent(ctx, canvasId, data, color, canvasWidth, canvasHeight);
|
||||
}
|
||||
}).exec();
|
||||
};
|
||||
|
||||
// 绘制图表内容
|
||||
const drawChartContent = (ctx, canvasId, data, color, canvasWidth, canvasHeight) => {
|
||||
// 清空画布
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
// 设置背景 - 透明背景
|
||||
ctx.setFillStyle('transparent');
|
||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight - 40);
|
||||
|
||||
// 绘制网格线
|
||||
ctx.setStrokeStyle('#f1f3f4');
|
||||
ctx.setLineWidth(1);
|
||||
|
||||
// 绘制水平网格线
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
const y = (canvasHeight - 40) * (i / 4);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, y);
|
||||
ctx.lineTo(canvasWidth, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// 绘制垂直网格线
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const x = (canvasWidth / 6) * i;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, 0);
|
||||
ctx.lineTo(x, canvasHeight - 40);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// 绘制数据线和填充区域
|
||||
if (data.length > 0) {
|
||||
const points = [];
|
||||
|
||||
// 计算所有点的坐标
|
||||
data.forEach((point, index) => {
|
||||
const x = (canvasWidth / 24) * (point.time + 0.5);
|
||||
let y;
|
||||
if (canvasId === 'temperatureChart') {
|
||||
y = (canvasHeight - 40) - ((point.value - 15) / 15) * (canvasHeight - 40);
|
||||
} else if (canvasId === 'humidityChart') {
|
||||
y = (canvasHeight - 40) - (point.value / 80) * (canvasHeight - 40);
|
||||
} else {
|
||||
y = (canvasHeight - 40) - (point.value / 60) * (canvasHeight - 40);
|
||||
}
|
||||
points.push({ x, y, value: point.value });
|
||||
});
|
||||
|
||||
// 绘制填充区域 - 透明色
|
||||
ctx.setFillStyle('transparent');
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(points[0].x, canvasHeight - 40);
|
||||
points.forEach(point => {
|
||||
ctx.lineTo(point.x, point.y);
|
||||
});
|
||||
ctx.lineTo(points[points.length - 1].x, canvasHeight - 40);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
// 绘制数据线
|
||||
ctx.setStrokeStyle(color);
|
||||
ctx.setLineWidth(3);
|
||||
ctx.beginPath();
|
||||
|
||||
points.forEach((point, index) => {
|
||||
if (index === 0) {
|
||||
ctx.moveTo(point.x, point.y);
|
||||
} else {
|
||||
ctx.lineTo(point.x, point.y);
|
||||
}
|
||||
});
|
||||
|
||||
ctx.stroke();
|
||||
|
||||
// 绘制数据点
|
||||
ctx.setFillStyle(color);
|
||||
points.forEach((point, index) => {
|
||||
if (index % 3 === 0) { // 每3个点显示一个数据点
|
||||
ctx.beginPath();
|
||||
ctx.arc(point.x, point.y, 4, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
|
||||
// 绘制数据点外圈
|
||||
ctx.setStrokeStyle('#ffffff');
|
||||
ctx.setLineWidth(2);
|
||||
ctx.stroke();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 绘制时间轴背景
|
||||
ctx.setFillStyle('rgba(248, 249, 250, 0.8)');
|
||||
ctx.fillRect(0, canvasHeight - 40, canvasWidth, 40);
|
||||
|
||||
// 绘制时间轴标签 - 显示0-23所有小时
|
||||
ctx.setFillStyle('#5f6368');
|
||||
ctx.setFontSize(20);
|
||||
ctx.setTextAlign('center');
|
||||
for (let i = 0; i <= 23; i += 2) { // 每2小时显示一个标签
|
||||
const x = (canvasWidth / 24) * (i + 0.5);
|
||||
ctx.fillText(i.toString(), x, canvasHeight - 12);
|
||||
}
|
||||
|
||||
ctx.draw();
|
||||
};
|
||||
|
||||
// 绘制所有图表
|
||||
const drawAllCharts = () => {
|
||||
nextTick(() => {
|
||||
drawChart('temperatureChart', temperatureData.value, '#ff6b35');
|
||||
drawChart('humidityChart', humidityData.value, '#4285f4');
|
||||
drawChart('pmChart', pmData.value, '#9c27b0');
|
||||
drawChart('pressureChart', pressureData.value, '#34a853');
|
||||
drawChart('windSpeedChart', windSpeedData.value, '#fbbc04');
|
||||
drawChart('lightChart', lightData.value, '#ea4335');
|
||||
});
|
||||
};
|
||||
|
||||
// 显示日期选择器
|
||||
const showDatePicker = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['2025年9月1日', '2025年8月31日', '2025年8月30日'],
|
||||
success: (res) => {
|
||||
const dates = ['2025年9月1日', '2025年8月31日', '2025年8月30日'];
|
||||
currentDate.value = dates[res.tapIndex];
|
||||
// 通过MQTT获取新日期的数据
|
||||
loadDataByDate(currentDate.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 根据日期加载数据
|
||||
const loadDataByDate = async (date) => {
|
||||
try {
|
||||
// 连接MQTT并获取数据
|
||||
await mqttService.connect();
|
||||
await mqttService.subscribeParameterData(date);
|
||||
|
||||
// 获取各参数的历史数据
|
||||
await Promise.all([
|
||||
mqttService.getHistoricalData(date, 'temperature'),
|
||||
mqttService.getHistoricalData(date, 'humidity'),
|
||||
mqttService.getHistoricalData(date, 'pm')
|
||||
]);
|
||||
|
||||
// 重新生成模拟数据并绘制图表
|
||||
initData();
|
||||
drawAllCharts();
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error);
|
||||
// 如果MQTT失败,使用模拟数据
|
||||
initData();
|
||||
drawAllCharts();
|
||||
}
|
||||
};
|
||||
|
||||
// 图表触摸事件
|
||||
const onChartTouch = (e) => {
|
||||
// 可以在这里添加图表交互功能
|
||||
console.log('Chart touched:', e);
|
||||
};
|
||||
|
||||
// 滚动事件处理
|
||||
let scrollTimer = null;
|
||||
|
||||
const onScroll = (e) => {
|
||||
isScrolling.value = true;
|
||||
|
||||
// 防抖处理,避免频繁触发
|
||||
if (scrollTimer) {
|
||||
clearTimeout(scrollTimer);
|
||||
}
|
||||
|
||||
scrollTimer = setTimeout(() => {
|
||||
isScrolling.value = false;
|
||||
}, 150);
|
||||
};
|
||||
|
||||
const onScrollToLower = () => {
|
||||
console.log('滚动到底部');
|
||||
// 可以在这里添加加载更多数据的逻辑
|
||||
};
|
||||
|
||||
// 组件挂载后初始化
|
||||
onMounted(() => {
|
||||
loadDataByDate(currentDate.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/common.scss';
|
||||
|
||||
.parameter-record-container {
|
||||
// 继承通用页面容器样式
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.date-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 24rpx;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||||
border: 1rpx solid #e8eaed;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.date-selector:hover {
|
||||
transform: translateY(-1rpx);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.date-text {
|
||||
font-size: 26rpx;
|
||||
color: #3c4043;
|
||||
margin-right: 12rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.date-icon {
|
||||
font-size: 20rpx;
|
||||
color: #1a73e8;
|
||||
font-weight: 600;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.date-selector:hover .date-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.charts-scroll-container {
|
||||
flex: 1;
|
||||
height: 0; /* 重要:配合flex: 1使用,确保正确计算高度 */
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* 滚动条样式 */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #dadce0 #f1f3f4;
|
||||
/* 平滑滚动 */
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Webkit浏览器滚动条样式 */
|
||||
.charts-scroll-container::-webkit-scrollbar {
|
||||
width: 8rpx;
|
||||
}
|
||||
|
||||
.charts-scroll-container::-webkit-scrollbar-track {
|
||||
background: rgba(241, 243, 244, 0.5);
|
||||
border-radius: 4rpx;
|
||||
margin: 4rpx 0;
|
||||
}
|
||||
|
||||
.charts-scroll-container::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #dadce0 0%, #bdc1c6 100%);
|
||||
border-radius: 4rpx;
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.2);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.charts-scroll-container::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #bdc1c6 0%, #9aa0a6 100%);
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.charts-scroll-container::-webkit-scrollbar-thumb:active {
|
||||
background: linear-gradient(180deg, #9aa0a6 0%, #5f6368 100%);
|
||||
}
|
||||
|
||||
.charts-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
// padding: 20rpx;
|
||||
}
|
||||
|
||||
.chart-card {
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
border: 1rpx solid #e8eaed;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.chart-card:hover {
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 1rpx solid #e8eaed;
|
||||
}
|
||||
|
||||
.chart-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rpx;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #3c4043;
|
||||
}
|
||||
|
||||
.chart-subtitle {
|
||||
font-size: 22rpx;
|
||||
color: #9aa0a6;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.chart-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
background: rgba(52, 168, 83, 0.1);
|
||||
border: 1rpx solid rgba(52, 168, 83, 0.2);
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.temperature-dot {
|
||||
background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
|
||||
box-shadow: 0 0 8rpx rgba(255, 107, 53, 0.3);
|
||||
}
|
||||
|
||||
.humidity-dot {
|
||||
background: linear-gradient(135deg, #4285f4 0%, #34a853 100%);
|
||||
box-shadow: 0 0 8rpx rgba(66, 133, 244, 0.3);
|
||||
}
|
||||
|
||||
.pm-dot {
|
||||
background: linear-gradient(135deg, #9c27b0 0%, #673ab7 100%);
|
||||
box-shadow: 0 0 8rpx rgba(156, 39, 176, 0.3);
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 22rpx;
|
||||
color: #34a853;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chart-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 16rpx;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.chart-canvas {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
background-color: transparent;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 30rpx;
|
||||
padding: 20rpx 10rpx 10rpx 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.content-bottom-spacing {
|
||||
height: 40rpx;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
// 响应式设计 - 平板设备适配
|
||||
@media (min-width: 768px) and (max-width: 1024px) {
|
||||
.date-text {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.chart-canvas {
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计 - 手机设备适配
|
||||
@media (max-width: 750rpx) {
|
||||
.date-text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.chart-canvas {
|
||||
height: 240rpx;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计 - 大屏设备适配
|
||||
@media (min-width: 1200px) {
|
||||
.date-text {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.chart-canvas {
|
||||
height: 420rpx;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user