diff --git a/.gitignore b/.gitignore index ab1f779..17e515b 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ build_upload.log *.spec *.zip .env +.env.* # frontend node_modules/ @@ -38,6 +39,7 @@ dist-ssr *.njsproj *.sln *.sw? +.vite # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/frontend/src/assets/styles/mobile.css b/frontend/src/assets/styles/mobile.css index dfabfa5..0c6b6bd 100644 --- a/frontend/src/assets/styles/mobile.css +++ b/frontend/src/assets/styles/mobile.css @@ -1,5 +1,14 @@ /* 移动端通用样式优化 */ +/* 标准断点变量 -- 通过CSS变量实现统一断点管理 */ +:root { + --mobile-xs-breakpoint: 480px; /* 小型手机设备 */ + --mobile-sm-breakpoint: 576px; /* 普通手机设备 */ + --mobile-md-breakpoint: 768px; /* 平板和大型手机 */ +} + +/* ===== 基础移动端组件 ===== */ + /* 增大触摸目标区域 */ .mobile-touch-target { min-height: 44px; /* 推荐的最小触摸目标尺寸 */ @@ -34,22 +43,22 @@ box-sizing: border-box; } -/* 自适应字体大小 */ -@media (max-width: 480px) { - .mobile-adaptive-text { - font-size: 14px; - } - - .mobile-adaptive-heading { - font-size: 18px; - } +/* ===== 移动端布局类 ===== */ + +/* 全宽容器 */ +.mobile-full-width { + width: 100% !important; + max-width: 100% !important; + margin-left: 0 !important; + margin-right: 0 !important; + box-sizing: border-box !important; } -/* 移动端表格优化 */ -.mobile-table-container { - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; +/* 移动端内容容器 */ +.mobile-content-container { + padding: 0.75rem !important; + width: 100% !important; + box-sizing: border-box !important; } /* 底部操作区固定 */ @@ -71,6 +80,15 @@ height: 60px; /* 预留底部空间 */ } +/* 底部背景延伸 */ +.mobile-bottom-extend { + position: relative; + padding-bottom: env(safe-area-inset-bottom, 0); + margin-bottom: -1px; /* 防止底部出现缝隙 */ +} + +/* ===== 移动端UI元素 ===== */ + /* 移动端友好的卡片样式 */ .mobile-card { border-radius: 12px !important; @@ -78,26 +96,23 @@ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important; } +/* 移动端卡片边距优化 */ +.mobile-card-spacing { + margin: 0.5rem 0 !important; + border-radius: 0.75rem !important; +} + +/* 移动端阴影优化 - 更轻微的阴影效果 */ +.mobile-shadow { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08) !important; +} + /* 移动端列表样式优化 */ .mobile-list-item { padding: 12px !important; } -/* 可滑动区域提示 */ -.mobile-scrollable-hint { - position: relative; -} - -.mobile-scrollable-hint::after { - content: ""; - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 24px; - background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.8)); - pointer-events: none; -} +/* ===== 特殊效果类 ===== */ /* 边框优化 */ .mobile-border-fix { @@ -122,42 +137,415 @@ pointer-events: none; } -/* 底部背景延伸 */ -.mobile-bottom-extend { +/* 可滑动区域提示 */ +.mobile-scrollable-hint { position: relative; - padding-bottom: env(safe-area-inset-bottom, 0); - margin-bottom: -1px; /* 防止底部出现缝隙 */ } -/* 全宽容器 */ -.mobile-full-width { +.mobile-scrollable-hint::after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 24px; + background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.8)); + pointer-events: none; +} + +/* 表格横向滚动指示器 */ +.mobile-table-scroll-indicator { + position: relative; +} +.mobile-table-scroll-indicator::after { + content: '←→'; + position: absolute; + bottom: 10px; + right: 10px; + color: rgba(32, 128, 240, 0.6); + font-size: 14px; + pointer-events: none; + z-index: 2; + animation: fadeInOut 2s infinite; +} + +@keyframes fadeInOut { + 0%, 100% { opacity: 0.4; } + 50% { opacity: 0.8; } +} + +/* ===== 响应式文本 ===== */ + +/* 自适应字体大小 */ +@media (max-width: 480px) { + .mobile-adaptive-text { + font-size: 14px; + } + + .mobile-adaptive-heading { + font-size: 18px; + } +} + +/* ===== 网格系统优化 ===== */ + +/* 网格布局基础类 */ +.mobile-grid { width: 100% !important; max-width: 100% !important; - margin-left: 0 !important; - margin-right: 0 !important; - box-sizing: border-box !important; } -/* 移动端卡片边距优化 */ -.mobile-card-spacing { - margin: 0.5rem 0 !important; - border-radius: 0.75rem !important; +.mobile-grid-item { + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; } -/* 移动端阴影优化 - 更轻微的阴影效果 */ -.mobile-shadow { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08) !important; -} +/* ===== API配置面板专用类 ===== */ -/* 移动端内容容器 - 确保内容不会太靠近边缘 */ -.mobile-content-container { +.mobile-connection-status { padding: 0.75rem !important; + border-radius: 0.5rem !important; + margin-top: 0.75rem !important; +} + +.mobile-api-config-section { + margin-bottom: 1.5rem !important; + width: 100% !important; +} + +.mobile-api-config-card { + padding: 0.5rem !important; + border-radius: 0.625rem !important; + margin-bottom: 1rem !important; +} + +.mobile-api-actions { + display: flex; + width: 100%; +} + +.mobile-api-buttons { + display: flex; + gap: 8px; +} + +.mobile-api-info-alert { + padding: 0.75rem !important; + margin-bottom: 0.75rem !important; + border-radius: 0.5rem !important; +} + +.mobile-model-chips { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.mobile-toggle-text { + font-size: 0.875rem; +} + +.mobile-api-save-option { + display: flex; + align-items: center; + width: 100%; +} + +.mobile-api-button { + height: 36px; + min-width: 40%; + display: flex; + align-items: center; + justify-content: center; +} + +.mobile-toggle-button { + font-weight: 500; + transition: all 0.3s ease; + border-radius: 16px; + padding: 4px 12px; +} + +/* ===== StockCard专用类 ===== */ + +.mobile-stock-card { width: 100% !important; box-sizing: border-box !important; + border-radius: 0.75rem !important; + overflow: hidden !important; + margin-bottom: 0.75rem; } +.mobile-card-header { + padding: 0.75rem !important; + border-bottom: 1px solid rgba(0, 0, 0, 0.05) !important; +} + +.mobile-card-content { + padding: 0.75rem !important; +} + +/* ===== StockSearch专用类 ===== */ + +.mobile-search-results { + max-width: 100%; + width: 100%; + border-radius: 0.75rem; + border: 1px solid var(--n-border-color, rgba(0, 0, 0, 0.1)); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.mobile-search-result-item { + padding: 0.625rem 0.875rem; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + min-height: 44px; /* 确保触摸区域足够大 */ +} + +.mobile-result-name { + max-width: 170px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* 小屏幕适配 */ +@media (max-width: 480px) { + .mobile-result-name { + max-width: 120px; + } + + .mobile-search-result-item { + padding: 0.5rem 0.75rem; + } + + .mobile-search-results { + border-radius: 0.625rem; + border: 1px solid rgba(0, 0, 0, 0.08); + } +} + +/* ===== MarketTimeDisplay专用类 ===== */ + +.mobile-market-time-card { + padding: 0.5rem; + margin-bottom: 1rem; + min-height: 180px; /* 移动端下的最小高度 */ +} + +.mobile-time-block { + padding: 0.625rem; + margin-bottom: 0.75rem; /* 增加底部外边距 */ +} + +.mobile-current-time { + font-size: 1.5rem; +} + +.mobile-time-label { + font-size: 0.9375rem; + margin-bottom: 0.5rem; +} + +.mobile-status-tag { + min-width: 100px; /* 减小移动端下的最小宽度 */ + height: 36px !important; + font-size: 0.875rem; /* 减小字体大小 */ +} + +.mobile-time-counter { + font-size: 0.75rem; /* 减小字体大小 */ + margin-top: 0.375rem; +} + +/* 小屏幕特殊适配 */ +@media (max-width: 480px) { + .mobile-market-time-card { + padding: 0.375rem; + min-height: 160px; /* 小屏幕下的最小高度 */ + } + + .mobile-time-block { + padding: 0.5rem; + margin-bottom: 1rem; /* 增加小屏幕下的底部外边距 */ + } + + .mobile-current-time { + font-size: 1.25rem; + } + + .mobile-time-label { + font-size: 0.875rem; + } + + .mobile-time-counter { + font-size: 0.75rem; + } + + .mobile-status-tag { + min-width: 90px; /* 进一步减小最小宽度 */ + font-size: 0.8125rem; + padding: 0 12px !important; /* 减小内边距 */ + } +} + +/* ===== 媒体查询部分 ===== */ + +/* 平板和大型手机 - 768px以下 */ +@media (max-width: 768px) { + .mobile-content-container { + padding: 0.75rem !important; + } + + .mobile-api-actions { + flex-direction: column !important; + align-items: flex-start !important; + } + + .mobile-api-buttons { + width: 100% !important; + justify-content: space-between !important; + margin-top: 0.75rem !important; + } + + .mobile-api-config-card { + padding: 0.75rem !important; + width: 100% !important; + box-sizing: border-box !important; + border-radius: 0.75rem !important; + overflow: hidden !important; + border: 1px solid rgba(0, 0, 0, 0.08) !important; + } + + .mobile-url-feedback { + flex-direction: column !important; + width: 100% !important; + } + + /* 网格优化 */ + :deep(.n-grid) { + gap: 12px !important; + margin-bottom: 12px !important; + } + + :deep(.n-grid-item) { + margin-bottom: 12px !important; + } +} + +/* 普通手机设备 - 480px以下 */ @media (max-width: 480px) { .mobile-content-container { padding: 0.5rem !important; } + + .mobile-api-config-section { + padding-bottom: 15px !important; + } + + .mobile-api-config-card { + padding: 0.5rem !important; + min-height: 80px !important; + } + + /* 小屏幕网格优化 */ + .mobile-grid-small { + width: 100% !important; + max-width: 100% !important; + gap: 8px !important; + } + + .mobile-grid-item-small { + padding: 0 !important; + margin-bottom: 8px !important; + } + + :deep(.n-grid) { + gap: 6px !important; + } + + :deep(.n-grid-item) { + padding: 0 !important; + margin-bottom: 6px !important; + } + + :deep(.n-grid-item) > * { + margin-bottom: 6px !important; + } + + .mobile-form-item { + margin-bottom: 8px !important; + } + + .mobile-api-buttons-small { + flex-wrap: wrap !important; + gap: 0.5rem !important; + } + + .mobile-api-button { + flex: 1 !important; + } + + .mobile-toggle-button { + width: 100% !important; + } + + .mobile-api-info-alert-small { + padding: 0.5rem !important; + margin-bottom: 0.5rem !important; + font-size: 0.75rem !important; + } + + .mobile-model-tag { + font-size: 0.75rem !important; + padding: 0 0.5rem !important; + } +} + +/* ===== AnnouncementBanner专用类 ===== */ + +.mobile-announcement-container { + max-width: 100%; + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.mobile-announcement-header { + font-size: 0.9375rem; +} + +.mobile-announcement-content { + font-size: 0.875rem; +} + +.mobile-announcement-timer { + font-size: 0.75rem; +} + +.mobile-login-announcement { + top: 0.75rem; + right: 0.75rem; + left: 0.75rem; +} + +/* 小屏幕适配 */ +@media (max-width: 480px) { + .mobile-announcement-container { + top: 0.25rem; + right: 0.25rem; + left: 0.25rem; + max-width: calc(100% - 0.5rem); + } + + .mobile-announcement-header { + font-size: 0.875rem; + } + + .mobile-announcement-content { + font-size: 0.8125rem; + } + + .mobile-announcement-timer { + font-size: 0.6875rem; + } } \ No newline at end of file diff --git a/frontend/src/components/AnnouncementBanner.vue b/frontend/src/components/AnnouncementBanner.vue index 5994278..b00582b 100644 --- a/frontend/src/components/AnnouncementBanner.vue +++ b/frontend/src/components/AnnouncementBanner.vue @@ -1,14 +1,14 @@