Skip to content

Commit 4868435

Browse files
committed
feat(web): 优化移动端显示效果
- 新增 ≤768px/≤480px/≤360px 三档响应式断点 - 小屏卡片单列横向布局,弹窗改为底部抽屉式 - 时间范围选择器允许换行,触控目标增大 - ECharts tooltip confine 防溢出、legend 移动端滚动模式 - 横竖屏切换自动重应用响应式配置 - 输入框 font-size:16px 避免 iOS 自动缩放
1 parent 6b4983d commit 4868435

1 file changed

Lines changed: 170 additions & 4 deletions

File tree

aircat-server-py/templates/sqlite.html

Lines changed: 170 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,152 @@
759759
font-size: 22px;
760760
}
761761
}
762+
763+
/* ===== 移动端优化 (≤768px 增强) ===== */
764+
@media (max-width: 768px) {
765+
/* 避免移动端 100vh 在浏览器工具栏出现时跳动 */
766+
.overlay {
767+
align-items: flex-end;
768+
padding: 0;
769+
}
770+
.modal {
771+
max-width: 100%;
772+
width: 100%;
773+
max-height: 92vh;
774+
border-radius: 16px 16px 0 0;
775+
animation: slideUp 0.22s ease;
776+
}
777+
@keyframes slideUp {
778+
from { transform: translateY(100%); }
779+
to { transform: translateY(0); }
780+
}
781+
.modal-header {
782+
padding: 14px 16px;
783+
}
784+
.modal-header h2 {
785+
font-size: 16px;
786+
}
787+
.modal-body {
788+
padding: 16px;
789+
}
790+
.modal-footer {
791+
position: sticky;
792+
bottom: 0;
793+
background: var(--bg-card);
794+
border-top: 1px solid var(--border);
795+
padding: 12px 16px;
796+
}
797+
/* 时间范围选择器允许换行,避免溢出 */
798+
.chart-header {
799+
flex-direction: column;
800+
align-items: stretch;
801+
}
802+
.range-selector {
803+
flex-wrap: wrap;
804+
justify-content: center;
805+
}
806+
.range-selector button {
807+
flex: 1 1 auto;
808+
min-width: 56px;
809+
padding: 8px 10px;
810+
}
811+
/* 触控目标增大,避免误触 */
812+
.gear-btn {
813+
width: 40px;
814+
height: 40px;
815+
}
816+
.btn {
817+
min-height: 42px;
818+
}
819+
}
820+
821+
/* ===== 小屏手机 (≤480px) ===== */
822+
@media (max-width: 480px) {
823+
.container {
824+
padding: 10px;
825+
}
826+
/* 卡片单列,避免窄屏挤压 */
827+
.cards {
828+
grid-template-columns: 1fr;
829+
gap: 10px;
830+
margin-bottom: 16px;
831+
}
832+
.card {
833+
padding: 14px;
834+
flex-direction: row;
835+
align-items: center;
836+
justify-content: space-between;
837+
gap: 12px;
838+
}
839+
.card::before {
840+
width: 100%;
841+
height: 3px;
842+
}
843+
.card-top {
844+
flex: 1;
845+
}
846+
.card-value .num {
847+
font-size: 28px;
848+
}
849+
/* 标题与状态纵向堆叠 */
850+
.header {
851+
flex-direction: column;
852+
align-items: flex-start;
853+
gap: 8px;
854+
padding: 16px 0 14px;
855+
margin-bottom: 16px;
856+
}
857+
.header h1 {
858+
font-size: 17px;
859+
}
860+
.header-right {
861+
width: 100%;
862+
justify-content: space-between;
863+
gap: 10px;
864+
}
865+
.status {
866+
font-size: 12px;
867+
}
868+
/* 图表更短,避免上下滚动 */
869+
.chart-section {
870+
padding: 12px;
871+
}
872+
#chart {
873+
height: 260px;
874+
}
875+
/* 设置项紧凑化 */
876+
.field input[type="text"],
877+
.field input[type="password"],
878+
.field input[type="number"],
879+
.field input[type="time"],
880+
.field select {
881+
padding: 11px 12px;
882+
font-size: 16px; /* 避免 iOS 自动缩放 */
883+
}
884+
.section {
885+
gap: 10px;
886+
}
887+
/* 登录/确认弹窗紧凑化 */
888+
.login-overlay .modal,
889+
.confirm-overlay .modal {
890+
max-width: 100%;
891+
}
892+
}
893+
894+
/* ===== 超小屏 (≤360px) ===== */
895+
@media (max-width: 360px) {
896+
.container {
897+
padding: 8px;
898+
}
899+
.card-value .num {
900+
font-size: 24px;
901+
}
902+
.range-selector button {
903+
min-width: 48px;
904+
padding: 7px 8px;
905+
font-size: 12px;
906+
}
907+
}
762908
</style>
763909
</head>
764910
<body>
@@ -1433,18 +1579,20 @@ <h2 id="login-title">登录</h2>
14331579
chart = echarts.init(document.getElementById("chart"), null, {
14341580
renderer: "canvas"
14351581
});
1582+
var isMobile = window.innerWidth <= 768;
14361583
var option = {
14371584
backgroundColor: "transparent",
14381585
color: ["#42a5f5", "#ff7043", "#ab47bc", "#00e676"],
14391586
grid: {
14401587
top: 50,
14411588
left: 12,
14421589
right: 12,
1443-
bottom: 70,
1590+
bottom: isMobile ? 80 : 70,
14441591
containLabel: true
14451592
},
14461593
tooltip: {
14471594
trigger: "axis",
1595+
confine: true,
14481596
backgroundColor: "rgba(22, 27, 34, 0.95)",
14491597
borderColor: "#30363d",
14501598
borderWidth: 1,
@@ -1479,11 +1627,14 @@ <h2 id="login-title">登录</h2>
14791627
legend: {
14801628
data: ["湿度", "温度", "PM2.5", "甲醛"],
14811629
top: 8,
1630+
type: isMobile ? "scroll" : "plain",
14821631
textStyle: { color: "#8b949e", fontSize: 12 },
14831632
inactiveColor: "#444c56",
14841633
itemWidth: 14,
14851634
itemHeight: 10,
1486-
itemGap: 18
1635+
itemGap: isMobile ? 10 : 18,
1636+
pageIconColor: "#00e676",
1637+
pageTextStyle: { color: "#8b949e" }
14871638
},
14881639
xAxis: {
14891640
type: "time",
@@ -1517,7 +1668,7 @@ <h2 id="login-title">登录</h2>
15171668
{
15181669
type: "slider",
15191670
bottom: 12,
1520-
height: 22,
1671+
height: isMobile ? 28 : 22,
15211672
backgroundColor: "#0d1117",
15221673
borderColor: "#30363d",
15231674
fillerColor: "rgba(0, 230, 118, 0.12)",
@@ -1588,8 +1739,23 @@ <h2 id="login-title">登录</h2>
15881739
]
15891740
};
15901741
chart.setOption(option);
1742+
var lastMobile = isMobile;
15911743
window.addEventListener("resize", function () {
1592-
if (chart) { chart.resize(); }
1744+
if (!chart) { return; }
1745+
chart.resize();
1746+
// 横竖屏切换跨越 768px 时,重新应用响应式配置
1747+
var nowMobile = window.innerWidth <= 768;
1748+
if (nowMobile !== lastMobile) {
1749+
lastMobile = nowMobile;
1750+
chart.setOption({
1751+
grid: { bottom: nowMobile ? 80 : 70 },
1752+
legend: {
1753+
type: nowMobile ? "scroll" : "plain",
1754+
itemGap: nowMobile ? 10 : 18
1755+
},
1756+
dataZoom: [{ height: nowMobile ? 28 : 22 }, {}]
1757+
});
1758+
}
15931759
});
15941760
}
15951761

0 commit comments

Comments
 (0)