feat: 概览页移除类目分布,检索按钮与输入框同高对齐
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
||||
FileTextOutlined,
|
||||
QuestionCircleOutlined,
|
||||
ReloadOutlined,
|
||||
AppstoreOutlined,
|
||||
SearchOutlined,
|
||||
SettingOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
@@ -147,36 +146,6 @@ const cards = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const categoryBars = computed(() => {
|
||||
const categories = statsData.value?.categories || {}
|
||||
const entries = Object.entries(categories).map(([name, count]) => ({ name, count }))
|
||||
entries.sort((a, b) => b.count - a.count)
|
||||
const max = entries.reduce((acc, item) => Math.max(acc, item.count), 1)
|
||||
const total = entries.reduce((acc, item) => acc + item.count, 0)
|
||||
return entries.map((item) => ({
|
||||
...item,
|
||||
percent: Math.round((item.count / max) * 100),
|
||||
ratio: total ? Math.round((item.count / total) * 100) : 0
|
||||
}))
|
||||
})
|
||||
|
||||
const gradientColors = [
|
||||
'linear-gradient(90deg, #1677ff 0%, #4096ff 100%)',
|
||||
'linear-gradient(90deg, #722ed1 0%, #9254de 100%)',
|
||||
'linear-gradient(90deg, #13c2c2 0%, #36cfc9 100%)',
|
||||
'linear-gradient(90deg, #fa8c16 0%, #ffa940 100%)',
|
||||
'linear-gradient(90deg, #52c41a 0%, #73d13d 100%)',
|
||||
'linear-gradient(90deg, #eb2f96 0%, #f759ab 100%)',
|
||||
'linear-gradient(90deg, #fa541c 0%, #ff7a45 100%)',
|
||||
'linear-gradient(90deg, #2f54eb 0%, #597ef7 100%)',
|
||||
'linear-gradient(90deg, #08979c 0%, #13c2c2 100%)',
|
||||
'linear-gradient(90deg, #c41d7f 0%, #eb2f96 100%)'
|
||||
]
|
||||
|
||||
function barGradient(index) {
|
||||
return gradientColors[index % gradientColors.length]
|
||||
}
|
||||
|
||||
async function loadStats() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
@@ -310,38 +279,6 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 类目分布 -->
|
||||
<div class="overview__section">
|
||||
<div class="overview__section-head">
|
||||
<h3 class="overview__subtitle">
|
||||
<AppstoreOutlined />
|
||||
<span>类目分布</span>
|
||||
</h3>
|
||||
<span v-if="categoryBars.length" class="text-muted overview__section-meta">
|
||||
共 {{ categoryBars.length }} 个类目
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="categoryBars.length === 0" class="overview__empty text-muted">暂无数据</div>
|
||||
<div v-else class="overview__bars">
|
||||
<div
|
||||
v-for="(bar, idx) in categoryBars"
|
||||
:key="bar.name"
|
||||
class="overview__bar-row"
|
||||
:title="`${bar.name}: ${bar.count} (${bar.ratio}%)`"
|
||||
>
|
||||
<span class="overview__bar-name" :title="bar.name">{{ bar.name }}</span>
|
||||
<div class="overview__bar-track">
|
||||
<div
|
||||
class="overview__bar-fill"
|
||||
:style="{ width: bar.percent + '%', background: barGradient(idx) }"
|
||||
/>
|
||||
</div>
|
||||
<span class="overview__bar-count">{{ bar.count }}</span>
|
||||
<span class="overview__bar-ratio">{{ bar.ratio }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 检索参数设置弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="paramsVisible"
|
||||
@@ -402,7 +339,7 @@ onMounted(() => {
|
||||
|
||||
.overview__search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
max-width: 760px;
|
||||
@@ -412,14 +349,22 @@ onMounted(() => {
|
||||
.overview__search-form {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.overview__search-form-item {
|
||||
flex: 1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.overview__search-form-item .ant-form-item-control {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.overview__search-input {
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.overview__search-params {
|
||||
@@ -489,94 +434,7 @@ onMounted(() => {
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.overview__section {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.overview__section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.overview__subtitle {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
margin: 0 0 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.overview__section-meta {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.overview__empty {
|
||||
text-align: center;
|
||||
padding: 32px 0;
|
||||
}
|
||||
|
||||
.overview__bars {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.overview__bar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.overview__bar-name {
|
||||
width: 180px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #374151;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.overview__bar-track {
|
||||
flex: 1;
|
||||
background: #f3f4f6;
|
||||
border-radius: 4px;
|
||||
height: 18px;
|
||||
margin: 0 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.overview__bar-fill {
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
min-width: 2px;
|
||||
transition: width 0.4s ease;
|
||||
}
|
||||
|
||||
.overview__bar-count {
|
||||
width: 48px;
|
||||
text-align: right;
|
||||
color: #1f2937;
|
||||
font-weight: 600;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.overview__bar-ratio {
|
||||
width: 48px;
|
||||
text-align: right;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.overview__bar-name {
|
||||
width: 120px;
|
||||
}
|
||||
.overview__search-bar {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user