main
parent
5e40a11ce1
commit
dc5658513c
@ -0,0 +1,12 @@ |
||||
<template> |
||||
<router-view /> |
||||
</template> |
||||
|
||||
<script setup> |
||||
// 路由入口组件,用于管理不同页面的切换 |
||||
</script> |
||||
|
||||
<style> |
||||
/* 路由入口样式重置 */ |
||||
/* 注意:不要在这里设置overflow,让各页面自己控制 */ |
||||
</style> |
||||
@ -1,5 +1,6 @@ |
||||
import { createApp } from 'vue' |
||||
import App from './App.vue' |
||||
import RouterApp from './RouterApp.vue' |
||||
import router from './router' |
||||
import './styles/index.scss' |
||||
|
||||
createApp(App).mount('#app')
|
||||
createApp(RouterApp).use(router).mount('#app')
|
||||
@ -0,0 +1,23 @@ |
||||
import { createRouter, createWebHistory } from 'vue-router' |
||||
import Dashboard from '../views/Dashboard.vue' |
||||
import TV86Display from '../views/TV86Display.vue' |
||||
|
||||
const routes = [ |
||||
{ |
||||
path: '/', |
||||
name: 'Dashboard', |
||||
component: Dashboard |
||||
}, |
||||
{ |
||||
path: '/tv86', |
||||
name: 'TV86Display', |
||||
component: TV86Display |
||||
} |
||||
] |
||||
|
||||
const router = createRouter({ |
||||
history: createWebHistory(), |
||||
routes |
||||
}) |
||||
|
||||
export default router
|
||||
@ -0,0 +1,469 @@ |
||||
<template> |
||||
<div class="dashboard-container"> |
||||
<!-- 标题区域 --> |
||||
<div class="header-section"> |
||||
<div class="header-info left"> |
||||
<!-- <div class="info-item"> |
||||
<span class="status-indicator" :class="isLayoutReady ? 'online' : 'loading'"></span> |
||||
<span>{{ isLayoutReady ? '系统运行正常' : '系统初始化中' }}</span> |
||||
</div> --> |
||||
</div> |
||||
<h1 class="main-title">{{ config?.screen?.title || '智慧活畜交易大数据中心' }}</h1> |
||||
<div class="header-info right"> |
||||
<div class="info-item"> |
||||
<span class="current-time">{{ currentTime || '--:--:--' }}</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 主要内容区域 --> |
||||
<div v-if="isLayoutReady" class="main-content"> |
||||
<!-- 左侧区域 - 分为左和左中两列 --> |
||||
<div class="left-section"> |
||||
<!-- 左列 --> |
||||
<div class="left-column"> |
||||
<div class="left-top"> |
||||
<RealTimeStats /> |
||||
</div> |
||||
<div class="left-bottom"> |
||||
<YakTradingData /> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 左中列 --> |
||||
<div class="left-center-column"> |
||||
<div class="left-center-top"> |
||||
<ComprehensiveSalesStats /> |
||||
</div> |
||||
<div class="left-center-bottom"> |
||||
<YakPriceTrend /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 中央区域 --> |
||||
<div class="center-section"> |
||||
<div class="map-container"> |
||||
<ChinaMap /> |
||||
<!-- <ScrollingAnnouncement /> --> |
||||
<!-- <div class="floating-table"> |
||||
<TransactionDetails /> |
||||
</div> --> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 右侧区域 - 分为右中和右两列 --> |
||||
<div class="right-section"> |
||||
<!-- 当供应信息展开时,整个右侧区域显示供应信息 --> |
||||
<div v-if="isSupplyExpanded" class="expanded-supply-container"> |
||||
<SupplyDemandData :force-expanded="true" @expand-change="handleSupplyExpand" /> |
||||
</div> |
||||
|
||||
<!-- 正常状态下的右侧布局 --> |
||||
<template v-else> |
||||
<!-- 右中列 --> |
||||
<div class="right-center-column"> |
||||
<div class="right-center-top"> |
||||
<ExchangeMonitor /> |
||||
</div> |
||||
<div class="right-center-middle"> |
||||
<YakSalesTypeStats /> |
||||
</div> |
||||
<div class="right-center-bottom"> |
||||
<PurchaserAnalysis /> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 右列 --> |
||||
<div class="right-column"> |
||||
<div class="right-bottom"> |
||||
<SupplyDemandData :force-expanded="false" @expand-change="handleSupplyExpand" /> |
||||
</div> |
||||
<div class="right-middle"> |
||||
<MarketRealtimeMonitor /> |
||||
</div> |
||||
<div class="right-top"> |
||||
<MarketEnvironmentMonitor /> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 加载状态 --> |
||||
<div v-else class="loading-container"> |
||||
<div class="loading-content"> |
||||
<div class="loading-spinner"></div> |
||||
<div class="loading-text">正在初始化布局...</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { ref, onMounted, onUnmounted, nextTick } from 'vue' |
||||
import { configManager } from '../utils/config.js' |
||||
import { dataManager } from '../utils/dataManager.js' |
||||
import { dataUpdater } from '../utils/dataUpdater.js' |
||||
|
||||
// 导入组件 |
||||
import RealTimeStats from '../components/RealTimeStats.vue' |
||||
import YakTradingData from '../components/YakTradingData.vue' |
||||
import ComprehensiveSalesStats from '../components/ComprehensiveSalesStats.vue' |
||||
import YakPriceTrend from '../components/YakPriceTrend.vue' |
||||
import ChinaMap from '../components/ChinaMap.vue' |
||||
import ScrollingAnnouncement from '../components/ScrollingAnnouncement.vue' |
||||
import TransactionDetails from '../components/TransactionDetails.vue' |
||||
import ExchangeMonitor from '../components/ExchangeMonitor.vue' |
||||
import YakSalesTypeStats from '../components/YakSalesTypeStats.vue' |
||||
import PurchaserAnalysis from '../components/PurchaserAnalysis.vue' |
||||
import MarketEnvironmentMonitor from '../components/MarketEnvironmentMonitor.vue' |
||||
import MarketRealtimeMonitor from '../components/MarketRealtimeMonitor.vue' |
||||
import SupplyDemandData from '../components/SupplyDemandData.vue' |
||||
|
||||
// 响应式数据 |
||||
const config = ref(null) |
||||
const currentTime = ref('') |
||||
const isLayoutReady = ref(false) // 控制页面渲染时机 |
||||
const isSupplyExpanded = ref(false) // 控制供应信息组件是否展开 |
||||
|
||||
// 更新时间 |
||||
const updateTime = () => { |
||||
const now = new Date() |
||||
currentTime.value = now.toLocaleString('zh-CN', { |
||||
year: 'numeric', |
||||
month: '2-digit', |
||||
day: '2-digit', |
||||
hour: '2-digit', |
||||
minute: '2-digit', |
||||
second: '2-digit' |
||||
}) |
||||
} |
||||
|
||||
// 处理供应信息组件展开/收缩 |
||||
const handleSupplyExpand = (expanded) => { |
||||
isSupplyExpanded.value = expanded |
||||
} |
||||
|
||||
// 初始化配置和时间 |
||||
let timeTimer = null |
||||
|
||||
onMounted(async () => { |
||||
// 立即开始更新时间 |
||||
updateTime() |
||||
timeTimer = setInterval(updateTime, 1000) |
||||
|
||||
try { |
||||
// 加载配置 |
||||
console.log('Dashboard: 开始加载配置') |
||||
config.value = await configManager.loadConfig() |
||||
console.log('Dashboard: 配置加载完成', config.value) |
||||
|
||||
// 设置CSS变量 |
||||
console.log('Dashboard: 设置CSS变量') |
||||
configManager.setCSSVariables() |
||||
|
||||
// 等待CSS变量生效和DOM更新 |
||||
await nextTick() |
||||
|
||||
// 再等待一帧确保样式完全应用 |
||||
await new Promise(resolve => requestAnimationFrame(resolve)) |
||||
console.log('Dashboard: CSS变量已生效') |
||||
|
||||
// 加载数据配置 |
||||
console.log('Dashboard: 开始加载数据配置') |
||||
const loadedData = await dataManager.loadData() |
||||
console.log('Dashboard: 数据配置加载完成', loadedData) |
||||
|
||||
// 标记布局准备完成,开始渲染组件 |
||||
console.log('Dashboard: 布局准备完成,开始渲染组件') |
||||
isLayoutReady.value = true |
||||
|
||||
console.log('Dashboard 完全初始化完成') |
||||
} catch (error) { |
||||
console.error('Failed to initialize dashboard:', error) |
||||
// 使用默认配置 |
||||
config.value = configManager.getDefaultConfig() |
||||
configManager.setCSSVariables() |
||||
|
||||
// 等待DOM更新后显示页面 |
||||
await nextTick() |
||||
await new Promise(resolve => requestAnimationFrame(resolve)) |
||||
isLayoutReady.value = true |
||||
} |
||||
}) |
||||
|
||||
onUnmounted(() => { |
||||
if (timeTimer) { |
||||
clearInterval(timeTimer) |
||||
} |
||||
}) |
||||
</script> |
||||
|
||||
<style scoped> |
||||
/* Dashboard专用样式 - 4:1大屏布局 */ |
||||
.dashboard-container { |
||||
width: var(--screen-width, 5120px); |
||||
height: var(--screen-height, 1440px); |
||||
min-width: var(--screen-width, 5120px); |
||||
min-height: var(--screen-height, 1440px); |
||||
display: flex; |
||||
flex-direction: column; |
||||
padding: 20px; |
||||
background: |
||||
radial-gradient(ellipse at 30% 40%, rgba(64, 158, 255, 0.06) 0%, transparent 60%), |
||||
radial-gradient(ellipse at 70% 60%, rgba(139, 92, 246, 0.05) 0%, transparent 60%), |
||||
radial-gradient(ellipse at 50% 80%, rgba(0, 212, 170, 0.03) 0%, transparent 50%), |
||||
linear-gradient(135deg, #0a0e1a 0%, #0f1419 25%, #131825 50%, #0f1419 75%, #0a0e1a 100%); |
||||
overflow: hidden; |
||||
box-sizing: border-box; |
||||
gap: 20px; |
||||
position: relative; |
||||
} |
||||
|
||||
.dashboard-container::before { |
||||
content: ''; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
right: 0; |
||||
bottom: 0; |
||||
background: |
||||
linear-gradient(90deg, transparent 0%, rgba(64, 158, 255, 0.03) 50%, transparent 100%), |
||||
linear-gradient(0deg, transparent 0%, rgba(139, 92, 246, 0.03) 50%, transparent 100%), |
||||
radial-gradient(circle at 25% 25%, rgba(64, 158, 255, 0.05) 0%, transparent 50%), |
||||
radial-gradient(circle at 75% 75%, rgba(139, 92, 246, 0.05) 0%, transparent 50%); |
||||
pointer-events: none; |
||||
z-index: 1; |
||||
animation: backgroundShift 15s ease-in-out infinite; |
||||
} |
||||
|
||||
@keyframes backgroundShift { |
||||
0%, 100% { |
||||
opacity: 1; |
||||
} |
||||
50% { |
||||
opacity: 0.7; |
||||
} |
||||
} |
||||
|
||||
/* 响应式适配 - 针对4:1宽高比优化 */ |
||||
@media (max-width: 1919px) and (min-width: 1600px) { |
||||
.dashboard-container { |
||||
padding: 6px; |
||||
gap: 6px; |
||||
} |
||||
} |
||||
|
||||
@media (max-width: 1599px) { |
||||
.dashboard-container { |
||||
padding: 5px; |
||||
gap: 5px; |
||||
} |
||||
} |
||||
|
||||
/* 标题区域 */ |
||||
.header-section { |
||||
height: 84px; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
padding: 0 40px; |
||||
background: url('../images/大标题背景.png') center/contain no-repeat; |
||||
background-size: auto 84px; |
||||
border-radius: 12px; |
||||
backdrop-filter: blur(10px); |
||||
position: relative; |
||||
z-index: 10; |
||||
flex-shrink: 0; |
||||
background-size: 100% 84px; |
||||
} |
||||
|
||||
.main-title { |
||||
font-size: 36px; |
||||
font-weight: 700; |
||||
background: linear-gradient(180deg, #fff 50%, #44c1ff); |
||||
-webkit-background-clip: text; |
||||
-webkit-text-fill-color: transparent; |
||||
background-clip: text; |
||||
text-align: center; |
||||
letter-spacing: 3px; |
||||
text-shadow: 0 0 20px rgba(64, 158, 255, 0.5); |
||||
flex: 2; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
margin-bottom: 15px; |
||||
|
||||
} |
||||
|
||||
.header-info { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 24px; |
||||
flex: 1; |
||||
|
||||
&.left { |
||||
justify-content: flex-start; |
||||
} |
||||
|
||||
&.right { |
||||
justify-content: flex-end; |
||||
} |
||||
} |
||||
|
||||
.info-item { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 8px; |
||||
font-size: 14px; |
||||
color: #a0a8b8; |
||||
} |
||||
|
||||
.current-time { |
||||
font-family: 'Courier New', monospace; |
||||
font-weight: bold; |
||||
color: #409EFF; |
||||
} |
||||
|
||||
/* 主要内容区域 */ |
||||
.main-content { |
||||
flex: 1; |
||||
display: flex; |
||||
gap: 16px; |
||||
min-height: 0; |
||||
padding-bottom: 20px; |
||||
} |
||||
|
||||
/* 左侧区域布局 */ |
||||
.left-section { |
||||
flex: 1; |
||||
display: flex; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.left-column { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.left-center-column { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.left-top, |
||||
.left-bottom, |
||||
.left-center-top, |
||||
.left-center-bottom { |
||||
flex: 1; |
||||
min-height: 0; |
||||
} |
||||
|
||||
/* 中央区域布局 */ |
||||
.center-section { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.map-container { |
||||
position: relative; |
||||
flex: 1; |
||||
min-height: 0; |
||||
} |
||||
|
||||
.floating-table { |
||||
position: absolute; |
||||
bottom: 20px; |
||||
left: 20px; |
||||
right: 20px; |
||||
height: 200px; |
||||
background: rgba(26, 31, 46, 0.95); |
||||
border: 1px solid rgba(64, 158, 255, 0.4); |
||||
border-radius: 8px; |
||||
backdrop-filter: blur(10px); |
||||
z-index: 100; |
||||
} |
||||
|
||||
/* 右侧区域布局 */ |
||||
.right-section { |
||||
flex: 1; |
||||
display: flex; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.right-center-column { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.right-column { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 12px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
.right-center-top, |
||||
.right-center-middle, |
||||
.right-center-bottom, |
||||
.right-top, |
||||
.right-middle, |
||||
.right-bottom { |
||||
flex: 1; |
||||
min-height: 0; |
||||
} |
||||
|
||||
/* 展开供应信息的容器 */ |
||||
.expanded-supply-container { |
||||
flex: 1; |
||||
min-height: 0; |
||||
} |
||||
|
||||
/* 加载状态 */ |
||||
.loading-container { |
||||
flex: 1; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
|
||||
.loading-content { |
||||
text-align: center; |
||||
color: #a0a8b8; |
||||
} |
||||
|
||||
.loading-spinner { |
||||
width: 40px; |
||||
height: 40px; |
||||
border: 3px solid rgba(64, 158, 255, 0.3); |
||||
border-top: 3px solid #409EFF; |
||||
border-radius: 50%; |
||||
animation: spin 1s linear infinite; |
||||
margin: 0 auto 16px; |
||||
} |
||||
|
||||
.loading-text { |
||||
font-size: 14px; |
||||
color: #a0a8b8; |
||||
} |
||||
|
||||
@keyframes spin { |
||||
0% { transform: rotate(0deg); } |
||||
100% { transform: rotate(360deg); } |
||||
} |
||||
</style> |
||||
@ -0,0 +1,287 @@ |
||||
<template> |
||||
<div class="tv86-viewport"> |
||||
<div class="tv86-container" ref="containerRef"> |
||||
<!-- 顶部时间日期天气区域 --> |
||||
<div class="header-datetime"> |
||||
<div class="datetime-info"> |
||||
<span class="date">{{ currentDate }}</span> |
||||
<span class="weekday">{{ currentWeekday }}</span> |
||||
<span class="lunar">{{ lunarDate }}</span> |
||||
<span class="weather">{{ weather }}</span> |
||||
<span class="temperature">{{ temperature }}</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 主内容区域 --> |
||||
<div class="main-content"> |
||||
<!-- 左侧区域 --> |
||||
<div class="left-section"> |
||||
<!-- 左上:牦牛实时交易概况 --> |
||||
<div class="left-top"> |
||||
<YakTradingOverview /> |
||||
</div> |
||||
|
||||
<!-- 左下:活牛、鲜肉价格趋势 --> |
||||
<div class="left-bottom"> |
||||
<PriceTrendChart /> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 右侧:市场公告 --> |
||||
<div class="right-section"> |
||||
<MarketAnnouncements /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { ref, onMounted, onUnmounted } from 'vue' |
||||
import YakTradingOverview from '../components/TV86/YakTradingOverview.vue' |
||||
import PriceTrendChart from '../components/TV86/PriceTrendChart.vue' |
||||
import MarketAnnouncements from '../components/TV86/MarketAnnouncements.vue' |
||||
import { Lunar, Solar } from 'lunar-javascript' |
||||
|
||||
// 基准分辨率 |
||||
const BASE_WIDTH = 3840 |
||||
const BASE_HEIGHT = 2160 |
||||
|
||||
// 响应式数据 |
||||
const containerRef = ref(null) |
||||
const currentDate = ref('') |
||||
const currentWeekday = ref('') |
||||
const lunarDate = ref('') |
||||
const weather = ref('晴') |
||||
const temperature = ref('36°C') |
||||
|
||||
// 更新时间日期 |
||||
const updateDateTime = () => { |
||||
const now = new Date() |
||||
|
||||
// 格式化日期 |
||||
const year = now.getFullYear() |
||||
const month = now.getMonth() + 1 |
||||
const day = now.getDate() |
||||
currentDate.value = `${year}年${month}月${day}日` |
||||
|
||||
// 星期 |
||||
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'] |
||||
currentWeekday.value = weekdays[now.getDay()] |
||||
|
||||
// 真实农历日期计算 |
||||
try { |
||||
const solar = Solar.fromDate(now) |
||||
const lunar = solar.getLunar() |
||||
|
||||
// 获取农历信息 |
||||
const lunarMonth = lunar.getMonthInChinese() |
||||
const lunarDay = lunar.getDayInChinese() |
||||
|
||||
// 使用toString方法获取完整信息来检查闰月 |
||||
const lunarString = lunar.toString() |
||||
const isLeapMonth = lunarString.includes('闰') |
||||
|
||||
// 处理农历月份格式 |
||||
let monthName = lunarMonth |
||||
|
||||
// 标准化月份名称 |
||||
const monthMap = { |
||||
'正': '正月', |
||||
'一': '正月', |
||||
'二': '二月', |
||||
'三': '三月', |
||||
'四': '四月', |
||||
'五': '五月', |
||||
'六': '六月', |
||||
'七': '七月', |
||||
'八': '八月', |
||||
'九': '九月', |
||||
'十': '十月', |
||||
'冬': '冬月', |
||||
'腊': '腊月' |
||||
} |
||||
|
||||
if (monthMap[monthName]) { |
||||
monthName = monthMap[monthName] |
||||
} else if (!monthName.includes('月')) { |
||||
monthName = monthName + '月' |
||||
} |
||||
|
||||
// 处理闰月情况 |
||||
if (isLeapMonth && !monthName.startsWith('闰')) { |
||||
monthName = '闰' + monthName |
||||
} |
||||
|
||||
lunarDate.value = `农历${monthName}${lunarDay}` |
||||
} catch (error) { |
||||
console.error('农历计算错误:', error) |
||||
lunarDate.value = '农历计算中...' |
||||
} |
||||
} |
||||
|
||||
// 页面缩放适配 |
||||
const updateScale = () => { |
||||
if (!containerRef.value) return |
||||
|
||||
const windowWidth = window.innerWidth |
||||
const windowHeight = window.innerHeight |
||||
|
||||
// 计算缩放比例 |
||||
const scaleX = windowWidth / BASE_WIDTH |
||||
const scaleY = windowHeight / BASE_HEIGHT |
||||
|
||||
// 取较小的缩放比例,确保内容完全可见 |
||||
const scale = Math.min(scaleX, scaleY) |
||||
|
||||
// 应用缩放 |
||||
containerRef.value.style.transform = `scale(${scale})` |
||||
containerRef.value.style.transformOrigin = 'top left' |
||||
|
||||
// 调整容器位置,使其居中 |
||||
const scaledWidth = BASE_WIDTH * scale |
||||
const scaledHeight = BASE_HEIGHT * scale |
||||
|
||||
const offsetX = (windowWidth - scaledWidth) / 2 |
||||
const offsetY = (windowHeight - scaledHeight) / 2 |
||||
|
||||
containerRef.value.style.left = `${offsetX}px` |
||||
containerRef.value.style.top = `${offsetY}px` |
||||
} |
||||
|
||||
let timer = null |
||||
|
||||
onMounted(() => { |
||||
updateDateTime() |
||||
timer = setInterval(updateDateTime, 60000) // 每分钟更新一次 |
||||
|
||||
// 86寸电视页面专用:禁用页面滚动条 |
||||
document.body.style.overflow = 'hidden' |
||||
document.documentElement.style.overflow = 'hidden' |
||||
|
||||
// 初始化缩放 |
||||
updateScale() |
||||
|
||||
// 监听窗口大小变化 |
||||
window.addEventListener('resize', updateScale) |
||||
}) |
||||
|
||||
onUnmounted(() => { |
||||
if (timer) { |
||||
clearInterval(timer) |
||||
} |
||||
window.removeEventListener('resize', updateScale) |
||||
|
||||
// 恢复页面滚动条(当离开86寸电视页面时) |
||||
document.body.style.overflow = 'auto' |
||||
document.documentElement.style.overflow = 'auto' |
||||
}) |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.tv86-viewport { |
||||
width: 100vw; |
||||
height: 100vh; |
||||
background: #000000; |
||||
overflow: hidden; |
||||
position: relative; |
||||
} |
||||
|
||||
.tv86-container { |
||||
width: 3840px; |
||||
height: 2160px; |
||||
background: |
||||
radial-gradient(ellipse at 25% 25%, rgba(64, 158, 255, 0.08) 0%, transparent 50%), |
||||
radial-gradient(ellipse at 75% 75%, rgba(139, 92, 246, 0.06) 0%, transparent 50%), |
||||
linear-gradient(135deg, #0a0e1a 0%, #0f1419 25%, #131825 50%, #0f1419 75%, #0a0e1a 100%); |
||||
display: flex; |
||||
flex-direction: column; |
||||
font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif; |
||||
color: #ffffff; |
||||
overflow: hidden; |
||||
padding: 40px; |
||||
box-sizing: border-box; |
||||
position: absolute; |
||||
} |
||||
|
||||
/* 顶部时间日期天气区域 */ |
||||
.header-datetime { |
||||
height: 200px; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
margin-bottom: 40px; |
||||
} |
||||
|
||||
.datetime-info { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 80px; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.date { |
||||
color: #ffffff; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.weekday { |
||||
color: #409EFF; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.lunar { |
||||
color: #67C23A; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.weather { |
||||
color: #E6A23C; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.temperature { |
||||
color: #F56C6C; |
||||
font-size: 56px; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
/* 主内容区域 */ |
||||
.main-content { |
||||
flex: 1; |
||||
display: flex; |
||||
gap: 60px; |
||||
min-height: 0; |
||||
} |
||||
|
||||
/* 左侧区域 */ |
||||
.left-section { |
||||
flex: 2; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 40px; |
||||
} |
||||
|
||||
.left-top { |
||||
/* height: 400px; */ |
||||
flex-shrink: 0; |
||||
} |
||||
|
||||
.left-bottom { |
||||
flex: 1; |
||||
min-height: 0; |
||||
} |
||||
|
||||
/* 右侧区域 */ |
||||
.right-section { |
||||
flex: 1; |
||||
} |
||||
|
||||
/* 确保内容始终适配,移除响应式媒体查询 */ |
||||
/* 页面会通过JavaScript自动缩放来适配不同屏幕尺寸 */ |
||||
</style> |
||||
Loading…
Reference in new issue