修改页面布局

This commit is contained in:
2026-01-28 11:10:05 +08:00
parent 3e89513e8b
commit 8c5024a943
2 changed files with 130 additions and 86 deletions

View File

@@ -54,24 +54,32 @@
<view class="chart-section"> <view class="chart-section">
<view class="admin-card"> <view class="admin-card">
<view class="admin-card-header"> <view class="admin-card-header">
<text class="admin-card-title">订单</text> <view class="header-left">
<view class="title-icon">
<!-- 不用 emoji纯样式画一个“图表感”的小方块 -->
<view class="title-icon-mark"></view>
</view>
<text class="admin-card-title">订单</text>
</view>
<view class="chart-controls"> <view class="chart-controls">
<button <view
v-for="period in chartPeriods" v-for="p in chartPeriods"
:key="period.value" :key="p.value"
class="period-btn" class="seg-btn"
:class="{ 'active': selectedPeriod === period.value }" :class="{ active: selectedPeriod === p.value }"
@click="changePeriod(period.value)" @click="changePeriod(p.value)"
> >
{{ period.label }} <text class="seg-btn-text">{{ p.label }}</text>
</button> </view>
</view> </view>
</view> </view>
<view class="admin-card-body"> <view class="admin-card-body">
<!-- ECharts 组合图容器 --> <!-- 图表容器:你后面接 ECharts / uCharts 都挂这里 -->
<view class="echarts-container"> <view class="echarts-container">
<text class="chart-placeholder">📊 ECharts 组合图:柱状图(订单金额) + 折线图(订单数量)</text> <!-- 先空着也行;不要放 emoji 占位符 -->
<text class="chart-desc">时间粒度:{{ selectedPeriodLabel }}</text> 111
</view> </view>
</view> </view>
</view> </view>
@@ -146,7 +154,10 @@ const kpiData = ref({
// 图表配置 // 图表配置
const selectedPeriod = ref('30days') const selectedPeriod = ref('30days')
const selectedPeriodLabel = ref('30天') const selectedPeriodLabel = computed((): string => {
const hit = chartPeriods.value.find((x) => x.value === selectedPeriod.value)
return hit ? hit.label : ""
})
const chartPeriods = [ const chartPeriods = [
{ label: '30天', value: '30days' }, { label: '30天', value: '30days' },
@@ -155,6 +166,12 @@ const chartPeriods = [
{ label: '年', value: 'year' } { label: '年', value: 'year' }
] ]
type PeriodItem = {
label: string
value: string
}
// 方法 // 方法
const formatNumber = (num: number) => { const formatNumber = (num: number) => {
if (num >= 10000) { if (num >= 10000) {
@@ -178,6 +195,8 @@ const changePeriod = (period: string) => {
// TODO: 重新加载图表数据 // TODO: 重新加载图表数据
console.log('切换时间粒度:', period) console.log('切换时间粒度:', period)
} }
</script> </script>
<style> <style>
@@ -317,99 +336,118 @@ const changePeriod = (period: string) => {
} }
/* ===== 图表区域 ===== */ /* ===== 图表区域 ===== */
.chart-section {
margin-bottom: 24px;
}
.charts-row {
display: flex;
gap: 24px;
}
.chart-col { /* 卡片外观 */
flex: 1;
}
/* ===== Admin Card 组件样式 ===== */
.admin-card { .admin-card {
background-color: #ffffff; background: #ffffff;
border: 1px solid #e8e8e8;
border-radius: 8px; border-radius: 8px;
overflow: hidden; border: 1px solid #f0f0f0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
} }
/* 头部:左标题 + 右分段按钮(不换行) */
.admin-card-header { .admin-card-header {
padding: 24px 24px 0 24px; padding: 16px 24px 12px 24px;
display: flex; display: flex;
flex-direction: row;;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 24px; flex-wrap: nowrap; /* 防止被挤下去 */
.admin-card-title {
font-size: 18px;
font-weight: 600;
color: #262626;
}
.admin-card-body {
padding: 0 24px 24px 24px;
}
} }
.header-left {
/* ===== 图表控件 ===== */
.chart-controls {
display: flex; display: flex;
flex-direction: row;;
gap: 12px; align-items: center;
gap: 10px;
min-width: 0;
} }
.period-btn { .title-icon {
padding: 6px 16px; width: 28px;
border: 1px solid #d9d9d9; height: 28px;
background-color: #ffffff; border-radius: 14px;
border-radius: 6px; background: #e6f4ff;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
}
.period-btn:hover {
border-color: #1890ff;
color: #1890ff;
}
.period-btn.active {
background-color: #1890ff;
color: #ffffff;
border-color: #1890ff;
}
/* ===== ECharts 容器 ===== */
.echarts-container {
height: 350px;
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: #fafafa;
border: 1px solid #e8e8e8;
border-radius: 6px;
} }
.chart-placeholder { .title-icon-mark {
font-size: 16px; width: 14px;
color: #666666; height: 14px;
text-align: center; border-radius: 4px;
margin-bottom: 8px; background: #1677ff;
} }
.chart-desc { .admin-card-title {
font-size: 18px;
font-weight: 600;
color: #262626;
white-space: nowrap;
}
/* 分段控件:一整条外框 + 内部分段(完全贴近你第二张图右上角) */
.chart-controls {
display: flex;
flex-direction: row;;
align-items: center;
justify-content: center;;
border: 1px solid #d9d9d9;
border-radius: 4px;
overflow: hidden;
background: #ffffff;
flex-shrink: 0; /* 防止被压缩换行 */
}
.seg-btn {
height: 32px;
min-width: 44px;
padding: 0 14px;
display: flex;
align-items: center;
justify-content: center;
border-left: 1px solid #d9d9d9;
background: #ffffff;
}
.seg-btn:first-child {
border-left: 0;
}
.seg-btn-text {
font-size: 14px; font-size: 14px;
color: #999999; color: #262626;
text-align: center; line-height: 1;
}
.seg-btn.active {
background: #1677ff;
}
.seg-btn.active .seg-btn-text {
color: #ffffff;
}
/* ✅ 注意body 是 header 的兄弟,不要写进 header 嵌套里 */
.admin-card-body {
padding: 0 24px 16px 24px;
}
.echarts-container {
width: 100%;
height: 300px; /* 贴近截图比例 */
}
.charts-row{
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
margin-top: 16px;
}
/* 每个图表列容器 */
.chart-col{
min-width: 0; /* 防止 ECharts/SVG 内容把列撑爆 */
} }
/* ===== 响应式设计 ===== */ /* ===== 响应式设计 ===== */
@@ -422,6 +460,14 @@ const changePeriod = (period: string) => {
min-width: 45%; min-width: 45%;
flex: 0 0 auto; flex: 0 0 auto;
} }
.admin-card{
flex-wrap: warp;
}
.charts-row{
grid-template-columns: 1fr;
}
} }
@media (max-width: 768px) { @media (max-width: 768px) {
@@ -434,9 +480,6 @@ const changePeriod = (period: string) => {
width: 100%; width: 100%;
} }
.charts-row {
flex-direction: column;
}
.dashboard-page { .dashboard-page {
padding: 16px; padding: 16px;

View File

@@ -1108,6 +1108,7 @@ onMounted(() => {
.stats-cards { .stats-cards {
display: flex; display: flex;
flex-direction: row;
justify-content: space-between; justify-content: space-between;
margin-bottom: 40rpx; margin-bottom: 40rpx;
flex-wrap: wrap; flex-wrap: wrap;