修改价格行情模块
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
<script>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { use } from 'echarts/core'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { LineChart } from 'echarts/charts'
|
||||
import { LineChart, PieChart, BarChart } from 'echarts/charts'
|
||||
import { TitleComponent, TooltipComponent, GridComponent, LegendComponent } from 'echarts/components'
|
||||
import VChart from 'vue-echarts'
|
||||
|
||||
use([CanvasRenderer, LineChart, TitleComponent, TooltipComponent, GridComponent, LegendComponent])
|
||||
use([CanvasRenderer, LineChart, PieChart, BarChart, TitleComponent, TooltipComponent, GridComponent, LegendComponent])
|
||||
|
||||
export default {
|
||||
name: 'Price',
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
CQ: ['本地黄牛', '西门塔尔牛']
|
||||
}
|
||||
|
||||
const unit = ref('元/个')
|
||||
const unit = ref('元/斤')
|
||||
const days = ref([])
|
||||
const priceSeries = ref([])
|
||||
// 省内各地区牛数据列表
|
||||
@@ -98,6 +98,83 @@ export default {
|
||||
}]
|
||||
}))
|
||||
|
||||
// 品种占比统计(环形图)
|
||||
const breedPieOption = computed(() => {
|
||||
// 按左侧列表统计各品种出现次数作为占比;无数据时按照品种列表均匀分配
|
||||
const counts = new Map()
|
||||
if (regionRows.value.length) {
|
||||
regionRows.value.forEach(r => {
|
||||
const k = r.breed || '未知品种'
|
||||
counts.set(k, (counts.get(k) || 0) + 1)
|
||||
})
|
||||
} else {
|
||||
// 示例分布:根据索引给出不同权重
|
||||
breeds.value.forEach((b, i) => {
|
||||
counts.set(b, 10 + (i * 5))
|
||||
})
|
||||
}
|
||||
const data = Array.from(counts.entries()).map(([name, value]) => ({ name, value }))
|
||||
// 与大屏主体色一致的配色(青蓝系)
|
||||
const brandColors = ['#00d4ff', '#29e3ff', '#00b3f9', '#3bd1ff', '#0099ff', '#61eaff']
|
||||
return {
|
||||
color: brandColors,
|
||||
title: { text: '品种占比统计', left: 'center', top: 6, textStyle: { color: '#eaf7ff', fontSize: 14 } },
|
||||
legend: { right: 20, top: 'middle', orient: 'vertical', textStyle: { color: '#cfefff' }, itemWidth: 12, itemHeight: 12 },
|
||||
tooltip: { trigger: 'item' },
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: ['48%', '70%'],
|
||||
center: ['50%', '55%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: { show: false },
|
||||
emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold', formatter: '{b}: {d}%' } },
|
||||
itemStyle: {
|
||||
borderColor: '#011819',
|
||||
borderWidth: 6,
|
||||
borderRadius: 8
|
||||
},
|
||||
data
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
// 优先通过接口生成省内地区牛数据列表,失败则回退示例数据
|
||||
const fetchProvinceRegionRows = async () => {
|
||||
const url = '/api/cattle-data'
|
||||
try {
|
||||
const res = await fetch(url)
|
||||
const raw = await res.json()
|
||||
const list = Array.isArray(raw) ? raw : (Array.isArray(raw?.data) ? raw.data : [])
|
||||
const today = new Date()
|
||||
const fmt = (d) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`
|
||||
|
||||
// 仅保留当前省份的数据
|
||||
const filtered = list.filter(item => {
|
||||
const p = item.province ?? item.provinceName ?? ''
|
||||
return p === provinceName.value
|
||||
})
|
||||
|
||||
const rows = filtered.map((item, idx) => ({
|
||||
id: item.id ?? `${props.selectedProvince}-${idx}`,
|
||||
date: fmt(today),
|
||||
region: item.location ?? '',
|
||||
breed: item.type ?? item.breed ?? '',
|
||||
price: Number(item.price),
|
||||
delta: 0,
|
||||
up: false
|
||||
})).filter(r => r.region && r.breed && Number.isFinite(r.price))
|
||||
|
||||
if (rows.length > 0) {
|
||||
regionRows.value = rows
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} catch (e) {
|
||||
console.warn('[Price] 获取省内地区牛数据失败:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 生成省内地区牛数据列表(示例,固定为10行)
|
||||
const genRegionRows = () => {
|
||||
const today = new Date()
|
||||
@@ -154,6 +231,119 @@ export default {
|
||||
genData(row?.id)
|
||||
}
|
||||
|
||||
// 年度统计数据(示例)
|
||||
const statsYears = ref([ 2023, 2024,2025])
|
||||
const stockYears = ref([2023, 2024, 2025])
|
||||
const stockCounts = ref([]) // 存栏数量(万头)
|
||||
const slaughterCounts = ref([]) // 出栏数量(万头)
|
||||
|
||||
let stockAbortController = null
|
||||
|
||||
// provinces 接口参数映射:与 Home.vue 保持一致,以避免名称差异导致无数据
|
||||
const toApiProvinceParam = (name) => {
|
||||
const map = {
|
||||
'内蒙古自治区': '内蒙古',
|
||||
'四川省': '四川',
|
||||
'新疆维吾尔自治区': '新疆',
|
||||
'西藏自治区': '西藏',
|
||||
'宁夏回族自治区': '宁夏',
|
||||
'广西壮族自治区': '广西',
|
||||
'河北省': '河北',
|
||||
'山东省': '山东',
|
||||
'黑龙江省': '黑龙江',
|
||||
'吉林省': '吉林',
|
||||
'云南省': '云南',
|
||||
'甘肃省': '甘肃',
|
||||
'青海省': '青海',
|
||||
'贵州省': '贵州',
|
||||
'安徽省': '安徽',
|
||||
}
|
||||
return map[name] ?? name
|
||||
}
|
||||
|
||||
const fetchStockData = async () => {
|
||||
// 取消上一次未完成的请求
|
||||
if (stockAbortController) {
|
||||
stockAbortController.abort()
|
||||
}
|
||||
stockAbortController = new AbortController()
|
||||
|
||||
try {
|
||||
if (!provinceName.value) return
|
||||
const apiParam = toApiProvinceParam(provinceName.value)
|
||||
const url = `/api/cattle-data/provinces?province=${encodeURIComponent(apiParam)}`
|
||||
const res = await fetch(url, { signal: stockAbortController.signal })
|
||||
const raw = await res.json()
|
||||
|
||||
let data = raw
|
||||
if (raw.code === 200 && raw.data) {
|
||||
data = raw.data
|
||||
}
|
||||
|
||||
let target = data
|
||||
if (Array.isArray(data)) {
|
||||
target = data.find(d => d.province === provinceName.value || d.provinceName === provinceName.value)
|
||||
if (!target && data.length > 0) target = data[0]
|
||||
}
|
||||
|
||||
if (target) {
|
||||
stockCounts.value = [
|
||||
Number(target.inventory23th) || 0,
|
||||
Number(target.inventory24th) || 0,
|
||||
Number(target.inventory25th) || 0
|
||||
]
|
||||
// 同步设置出栏统计(与存栏相同来源)
|
||||
slaughterCounts.value = [
|
||||
Number(target.slaughter23th) || 0,
|
||||
Number(target.slaughter24th) || 0,
|
||||
Number(target.slaughter25th) || 0
|
||||
]
|
||||
} else {
|
||||
stockCounts.value = [0, 0, 0]
|
||||
slaughterCounts.value = [0, 0, 0]
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.name === 'AbortError') return
|
||||
console.error('获取存栏数据失败', e)
|
||||
stockCounts.value = [0, 0, 0]
|
||||
slaughterCounts.value = [0, 0, 0]
|
||||
} finally {
|
||||
stockAbortController = null
|
||||
}
|
||||
}
|
||||
|
||||
const genStats = () => {
|
||||
// 统一使用接口返回值,不再生成示例数据
|
||||
fetchStockData()
|
||||
}
|
||||
|
||||
const stockBarOption = computed(() => ({
|
||||
title: { text: '存栏统计', left: 'center', textStyle: { color: '#eaf7ff' } },
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: 40, right: 20, top: 50, bottom: 40 },
|
||||
xAxis: { type: 'category', data: stockYears.value, axisLabel: { color: '#cfefff' }, axisLine: { lineStyle: { color: '#2e6ba8' } } },
|
||||
yAxis: { type: 'value', axisLabel: { color: '#cfefff' }, splitLine: { lineStyle: { color: 'rgba(0,212,255,0.2)' } } },
|
||||
series: [{
|
||||
name: '存栏', type: 'bar', data: stockCounts.value,
|
||||
itemStyle: { color: '#00d4ff' },
|
||||
barWidth: '40%'
|
||||
}]
|
||||
}))
|
||||
|
||||
const slaughterLineOption = computed(() => ({
|
||||
title: { text: '出栏统计', left: 'center', textStyle: { color: '#eaf7ff' } },
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: 40, right: 20, top: 50, bottom: 40 },
|
||||
xAxis: { type: 'category', data: statsYears.value, axisLabel: { color: '#cfefff' }, axisLine: { lineStyle: { color: '#2e6ba8' } } },
|
||||
yAxis: { type: 'value', axisLabel: { color: '#cfefff' }, splitLine: { lineStyle: { color: 'rgba(0,212,255,0.2)' } } },
|
||||
series: [{
|
||||
name: '出栏', type: 'line', smooth: true, data: slaughterCounts.value,
|
||||
lineStyle: { color: '#29e3ff', width: 2 },
|
||||
itemStyle: { color: '#61eaff' },
|
||||
areaStyle: { color: 'rgba(0,212,255,0.12)' }
|
||||
}]
|
||||
}))
|
||||
|
||||
const yesterdayDelta = computed(() => {
|
||||
if (!priceSeries.value.length || priceSeries.value.length < 2) return 0
|
||||
const n = priceSeries.value.length
|
||||
@@ -170,12 +360,17 @@ export default {
|
||||
return d > 0 ? '↑' : '↓'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
genRegionRows()
|
||||
// 统一在选中省份变化时加载数据,并在初始化时立即执行一次
|
||||
watch(() => props.selectedProvince, async (newVal, oldVal) => {
|
||||
if (newVal === oldVal) return
|
||||
selectedRow.value = null
|
||||
const ok = await fetchProvinceRegionRows()
|
||||
if (!ok) genRegionRows()
|
||||
genData()
|
||||
})
|
||||
genStats()
|
||||
}, { immediate: true })
|
||||
|
||||
return { unit, provinceName, breeds, todayPrice, max7d, min7d, avg7d, avgToday, days, priceSeries, chartOption, regionRows, selectedRow, handleRowClick, isUnknownRegion, range, weight, setRange, setWeight, yesterdayDelta, trendText, trendSymbol }
|
||||
return { unit, provinceName, breeds, todayPrice, max7d, min7d, avg7d, avgToday, days, priceSeries, chartOption, breedPieOption, stockBarOption, slaughterLineOption, regionRows, selectedRow, handleRowClick, isUnknownRegion, range, weight, setRange, setWeight, yesterdayDelta, trendText, trendSymbol }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -188,79 +383,94 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="price-content">
|
||||
<section class="left-info">
|
||||
<div class="card region-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>省内各地区牛数据列表</h3>
|
||||
<!-- 第一行:左侧牛数据列表 + 右侧价格详情(等高) -->
|
||||
<div class="card region-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>省内各地区牛数据列表</h3>
|
||||
</div>
|
||||
<div class="region-table">
|
||||
<div class="table-header">
|
||||
<div class="th">时间</div>
|
||||
<div class="th">地区</div>
|
||||
<div class="th">品类</div>
|
||||
<div class="th">价格({{ unit }})</div>
|
||||
</div>
|
||||
<div class="region-table">
|
||||
<div class="table-header">
|
||||
<div class="th">时间</div>
|
||||
<div class="th">地区</div>
|
||||
<div class="th">品类</div>
|
||||
<div class="th">价格({{ unit }})</div>
|
||||
<div class="th">涨跌</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div class="table-row" v-for="row in regionRows" :key="row.id" @click="handleRowClick(row)" :class="{ active: selectedRow && selectedRow.id === row.id }">
|
||||
<div class="td">{{ row.date }}</div>
|
||||
<div class="td">{{ row.region }}</div>
|
||||
<div class="td">{{ row.breed }}</div>
|
||||
<div class="td">{{ row.price.toFixed(2) }}{{ unit }}</div>
|
||||
<div class="td">
|
||||
<span :class="row.delta === 0 ? 'change-zero' : (row.up ? 'change-up' : 'change-down')">
|
||||
{{ row.delta.toFixed(2) }}{{ unit }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div class="table-row" v-for="row in regionRows" :key="row.id" @click="handleRowClick(row)" :class="{ active: selectedRow && selectedRow.id === row.id }">
|
||||
<div class="td">{{ row.date }}</div>
|
||||
<div class="td">{{ row.region }}</div>
|
||||
<div class="td">{{ row.breed }}</div>
|
||||
<div class="td">{{ row.price.toFixed(2) }}{{ unit }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="right-stats">
|
||||
<div class="card detail-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>
|
||||
<span :class="{ highlight: isUnknownRegion(selectedRow ? selectedRow.region : provinceName) }">
|
||||
{{ (selectedRow ? selectedRow.region : provinceName) }}
|
||||
</span>
|
||||
价格详情
|
||||
</h3>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<div class="today-price-line">
|
||||
<div class="labels">
|
||||
<span class="label">今日批发均价</span>
|
||||
<span class="compare">相比昨日 <span :class="yesterdayDelta === 0 ? 'change-zero' : (yesterdayDelta > 0 ? 'change-up' : 'change-down')">{{ trendText }} {{ yesterdayDelta.toFixed(2) }}</span> <span class="symbol">{{ trendSymbol }}</span></span>
|
||||
</div>
|
||||
<div class="price-display">
|
||||
<span class="currency">¥</span>
|
||||
<span class="value">{{ avgToday.toFixed(2) }}</span>
|
||||
<span class="unit">{{ unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filters">
|
||||
<div class="weight-group">
|
||||
<button :class="['filter-btn', { active: weight === 'normal' }]" @click="setWeight('normal')">通货</button>
|
||||
<button :class="['filter-btn', { active: weight === '400' }]" @click="setWeight('400')">400斤</button>
|
||||
<button :class="['filter-btn', { active: weight === '500' }]" @click="setWeight('500')">500斤</button>
|
||||
</div>
|
||||
<div class="range-group">
|
||||
<button :class="['filter-btn', { active: range === 7 }]" @click="setRange(7)">近7天</button>
|
||||
<button :class="['filter-btn', { active: range === 30 }]" @click="setRange(30)">近30天</button>
|
||||
<button :class="['filter-btn', { active: range === 60 }]" @click="setRange(60)">近60天</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-chart class="trend-chart" :option="chartOption" autoresize />
|
||||
</div>
|
||||
<div class="card detail-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>
|
||||
<span :class="{ highlight: isUnknownRegion(selectedRow ? selectedRow.region : provinceName) }">
|
||||
{{ (selectedRow ? selectedRow.region : provinceName) }}
|
||||
</span>
|
||||
价格详情
|
||||
</h3>
|
||||
</div>
|
||||
</section>
|
||||
<div class="detail-content">
|
||||
<div class="today-price-line">
|
||||
<div class="labels">
|
||||
<span class="label">今日批发均价</span>
|
||||
<span class="compare">相比昨日 <span :class="yesterdayDelta === 0 ? 'change-zero' : (yesterdayDelta > 0 ? 'change-up' : 'change-down')">{{ trendText }} {{ yesterdayDelta.toFixed(2) }}</span> <span class="symbol">{{ trendSymbol }}</span></span>
|
||||
</div>
|
||||
<div class="price-display">
|
||||
<span class="currency">¥</span>
|
||||
<span class="value">{{ avgToday.toFixed(2) }}</span>
|
||||
<span class="unit">{{ unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filters">
|
||||
<div class="weight-group">
|
||||
<button :class="['filter-btn', { active: weight === 'normal' }]" @click="setWeight('normal')">通货</button>
|
||||
<button :class="['filter-btn', { active: weight === '400' }]" @click="setWeight('400')">400斤</button>
|
||||
<button :class="['filter-btn', { active: weight === '500' }]" @click="setWeight('500')">500斤</button>
|
||||
</div>
|
||||
<div class="range-group">
|
||||
<button :class="['filter-btn', { active: range === 7 }]" @click="setRange(7)">近7天</button>
|
||||
<button :class="['filter-btn', { active: range === 30 }]" @click="setRange(30)">近30天</button>
|
||||
<button :class="['filter-btn', { active: range === 60 }]" @click="setRange(60)">近60天</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-chart class="trend-chart" :option="chartOption" autoresize />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二行:左侧品种占比 + 中间存栏 + 右侧出栏(三列等宽) -->
|
||||
<div class="card breed-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>品种占比统计</h3>
|
||||
</div>
|
||||
<v-chart class="breed-donut" :option="breedPieOption" autoresize />
|
||||
</div>
|
||||
|
||||
<div class="card stock-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>存栏统计</h3>
|
||||
</div>
|
||||
<v-chart class="stock-chart" :option="stockBarOption" autoresize />
|
||||
</div>
|
||||
|
||||
<div class="card slaughter-card">
|
||||
<div class="panel-header">
|
||||
<div class="diamond-icon"></div>
|
||||
<h3>出栏统计</h3>
|
||||
</div>
|
||||
<v-chart class="slaughter-chart" :option="slaughterLineOption" autoresize />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -276,6 +486,7 @@ export default {
|
||||
gap: 16px;
|
||||
background: #011819; /* 与预警监测页背景一致 */
|
||||
position: relative;
|
||||
overflow: hidden; /* 页面高度固定,禁用整体滚动 */
|
||||
}
|
||||
|
||||
.price-page::before {
|
||||
@@ -312,8 +523,11 @@ export default {
|
||||
|
||||
.price-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 1.6fr; /* 加宽左侧列表区域 */
|
||||
grid-template-columns: repeat(6, 1fr); /* 6列,方便分配 3:3 和 2:2:2 */
|
||||
grid-template-rows: 1fr 1fr; /* 两行等高 */
|
||||
gap: 16px;
|
||||
flex: 1; /* 占满剩余高度 */
|
||||
min-height: 0; /* 允许内部滚动 */
|
||||
}
|
||||
|
||||
.card {
|
||||
@@ -324,8 +538,18 @@ export default {
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%; /* 与所在网格行高度一致 */
|
||||
display: flex;
|
||||
flex-direction: column; /* 让内部内容自适应高度 */
|
||||
}
|
||||
|
||||
/* 网格跨度设置 */
|
||||
.region-card { grid-column: span 3; }
|
||||
.detail-card { grid-column: span 3; }
|
||||
.breed-card { grid-column: span 2; }
|
||||
.stock-card { grid-column: span 2; }
|
||||
.slaughter-card { grid-column: span 2; }
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -396,23 +620,48 @@ export default {
|
||||
color: #cfefff;
|
||||
}
|
||||
|
||||
.right-stats {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
/* 移除旧的 .right-stats, .left-info, .stats-bottom 相关样式 */
|
||||
|
||||
.detail-card {
|
||||
.breed-card {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(0,212,255,0.25);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.breed-donut {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(0,212,255,0.25);
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px; /* 缩小内边距,降低模块总高度 */
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
gap: 8px; /* 收紧纵向间距 */
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.stock-card, .slaughter-card {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(0,212,255,0.25);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.stock-chart, .slaughter-chart {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.today-price-line {
|
||||
@@ -452,7 +701,7 @@ export default {
|
||||
|
||||
.table-header, .table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.6fr 1.2fr 1fr 1fr; /* 时间略窄,地区更宽,价格与涨跌等宽 */
|
||||
grid-template-columns: 1fr 1.6fr 1.2fr 1fr; /* 移除涨跌列后调整为四列 */
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -469,6 +718,37 @@ export default {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 缩小左侧“省内各地区牛数据列表”模块高度 - 移除固定高度 */
|
||||
.region-card .region-table {
|
||||
height: auto;
|
||||
flex: 1; /* 占据剩余空间 */
|
||||
min-height: 0; /* 允许压缩 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.region-card .region-table .table-body {
|
||||
height: auto;
|
||||
flex: 1; /* 占据剩余空间 */
|
||||
overflow-y: auto; /* 允许滚动 */
|
||||
min-height: 0; /* 允许压缩 */
|
||||
}
|
||||
|
||||
/* 自定义滚动条样式 */
|
||||
.region-card .region-table .table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
.region-card .region-table .table-body::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.region-card .region-table .table-body::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 212, 255, 0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.region-card .region-table .table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0, 212, 255, 0.5);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
padding: 18px 0; /* 增加上下内边距,提高行高 */
|
||||
min-height: 60px; /* 提高最小高度,列表更舒展 */
|
||||
@@ -535,18 +815,30 @@ export default {
|
||||
.stat-item .value { color: #eaffff; font-size: 22px; font-weight: bold; }
|
||||
.stat-item .unit { color: #9ed7ff; font-size: 12px; }
|
||||
|
||||
.trend-chart { width: 100%; height: 320px; }
|
||||
.trend-chart {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1366px) {
|
||||
.trend-chart { height: 280px; }
|
||||
.table-header, .table-row { grid-template-columns: 0.9fr 1.3fr 1fr 0.9fr 0.9fr; }
|
||||
.stats-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
/* 小屏幕下可能需要调整 */
|
||||
.trend-chart { height: auto; }
|
||||
.breed-donut { height: auto; }
|
||||
/* 保持6列布局,但可能需要调整字体或间距 */
|
||||
/* 如果太挤,可以改为第一行 3+3,第二行 2+2+2 仍然适用,或者改为 2列布局 */
|
||||
/* 这里暂时保持用户要求的布局 */
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.price-content { grid-template-columns: 1fr; }
|
||||
.table-header, .table-row { grid-template-columns: 1fr 1.2fr 1fr 0.9fr 0.9fr; }
|
||||
.breed-donut { height: 220px; }
|
||||
.trend-chart { height: 180px; }
|
||||
.stats-bottom { grid-template-columns: 1fr; }
|
||||
.table-header, .table-row { grid-template-columns: 1fr 1.2fr 1fr 0.9fr; }
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.th, .td { font-size: 13px; }
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user