fix: 模型库页面移动端适配

This commit is contained in:
Gsh
2025-12-24 23:25:07 +08:00
parent 7495dc86a0
commit 96a21210b5
2 changed files with 287 additions and 9 deletions

View File

@@ -1,13 +1,16 @@
<script setup lang="ts">
import type { ModelApiTypeOption, ModelLibraryDto, ModelTypeOption } from '@/api/model/types';
import { Box, CopyDocument, HomeFilled, OfficeBuilding, Search } from '@element-plus/icons-vue';
import { Box, Close, CopyDocument, HomeFilled, OfficeBuilding, Search } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { getApiTypeOptions, getModelLibraryList, getModelTypeOptions, getProviderList } from '@/api/model';
import { useScreenStore } from '@/hooks/useScreen';
const router = useRouter();
const { isMobile } = useScreenStore();
const showMobileFilter = ref(false);
const loading = ref(false);
const modelList = ref<ModelLibraryDto[]>([]);
const totalCount = ref(0);
@@ -201,6 +204,14 @@ watch([selectedProviders, selectedModelTypes, selectedApiTypes, isPremiumOnly],
fetchModelList();
}, { deep: true });
function openMobileFilter() {
showMobileFilter.value = true;
}
function closeMobileFilter() {
showMobileFilter.value = false;
}
onMounted(() => {
fetchProviderList();
fetchModelTypeOptions();
@@ -270,16 +281,24 @@ onMounted(() => {
<div class="main-content">
<div class="content-wrapper">
<!-- 左侧筛选栏 -->
<aside class="filter-sidebar">
<aside class="filter-sidebar" :class="{ 'mobile-active': showMobileFilter }">
<!-- 移动端遮罩 -->
<div v-if="isMobile && showMobileFilter" class="mobile-overlay" @click="closeMobileFilter" />
<div class="filter-section">
<div class="filter-header">
<h3 class="filter-title">
<el-icon><i-ep-filter /></el-icon>
筛选条件
</h3>
<el-button link type="primary" size="small" @click="resetFilters">
重置
</el-button>
<div class="filter-header-actions">
<el-button link type="primary" size="small" @click="resetFilters">
重置
</el-button>
<el-icon v-if="isMobile" class="close-btn" @click="closeMobileFilter">
<Close />
</el-icon>
</div>
</div>
<!-- 搜索框 -->
@@ -399,6 +418,13 @@ onMounted(() => {
<!-- 右侧模型列表 -->
<main class="model-list-section">
<!-- 移动端筛选按钮 -->
<div v-if="isMobile" class="mobile-filter-bar">
<el-button type="primary" :icon="Search" plain class="w-full" @click="openMobileFilter">
筛选与搜索
</el-button>
</div>
<!-- 加载状态 -->
<div v-if="loading" class="loading-wrapper">
<el-skeleton :rows="8" animated />
@@ -494,7 +520,7 @@ onMounted(() => {
v-model:page-size="pageSize"
:page-sizes="[12, 24, 48, 96]"
:total="totalCount"
layout="total, sizes, prev, pager, next, jumper"
:layout="isMobile ? 'prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
prev-text="上一页"
next-text="下一页"
background
@@ -883,6 +909,7 @@ onMounted(() => {
display: flex;
gap: 16px;
margin-bottom: 16px;
align-items: flex-start;
.model-icon {
width: 56px;
@@ -914,15 +941,19 @@ onMounted(() => {
.model-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: center;
.model-name {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 6px 0;
//overflow: hidden;
margin: 0 0 4px 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
padding-right: 24px; // 防止文字遮挡复制按钮
}
.model-provider {
@@ -948,7 +979,6 @@ onMounted(() => {
font-size: 11px;
color: #909399;
font-weight: 600;
//text-transform: uppercase;
letter-spacing: 0.5px;
}
@@ -1102,4 +1132,251 @@ onMounted(() => {
background-position: 0% 50%;
}
}
@media screen and (max-width: 768px) {
.model-library-container {
.banner-section {
padding: 24px 16px;
.banner-content {
.banner-header {
flex-direction: column;
align-items: stretch;
gap: 24px;
.banner-left {
flex-direction: column;
align-items: flex-start;
gap: 24px;
.stats-cards {
width: 100%;
flex-wrap: wrap;
.stat-card {
flex: 1;
min-width: 140px;
}
}
}
.home-btn {
width: 100%;
}
}
}
}
.main-content {
padding: 16px 12px;
.content-wrapper {
flex-direction: column;
padding: 0;
.filter-sidebar {
width: 0;
height: 0;
overflow: hidden;
&.mobile-active {
width: auto;
height: auto;
overflow: visible;
.mobile-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1999;
backdrop-filter: blur(4px);
}
.filter-section {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 80%;
max-width: 320px;
z-index: 2000;
border-radius: 0 16px 16px 0;
overflow-y: auto;
animation: slideIn 0.3s ease;
}
}
.filter-section {
margin: 0;
.filter-header {
.filter-header-actions {
display: flex;
align-items: center;
gap: 16px;
.close-btn {
font-size: 20px;
cursor: pointer;
color: #909399;
&:hover {
color: #606266;
}
}
}
}
}
}
.model-list-section {
.mobile-filter-bar {
margin-bottom: 16px;
position: sticky;
top: 0;
z-index: 100;
background: rgba(245, 247, 250, 0.95);
backdrop-filter: blur(10px);
padding: 12px 4px;
margin: -16px -4px 16px -4px;
.w-full {
width: 100%;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
}
.pagination-wrapper {
:deep(.el-pagination) {
.el-pagination__jump {
display: none !important;
}
}
}
.model-grid {
margin-bottom: 24px;
.model-card {
padding: 20px; // 增加内边距
margin-bottom: 16px; // 增加卡片间距
border-radius: 16px;
.copy-btn-corner {
top: 16px;
right: 16px;
width: 32px;
height: 32px;
font-size: 14px;
}
.model-card-header {
margin-bottom: 16px;
gap: 16px;
.model-icon {
width: 48px;
height: 48px;
.icon-placeholder {
font-size: 20px;
border-radius: 10px;
}
.icon-img {
border-radius: 10px;
}
}
.model-info {
.model-name {
font-size: 17px;
margin-bottom: 4px;
padding-right: 36px; // 移动端预留更多空间给复制按钮
}
.model-provider {
font-size: 13px;
}
}
}
.model-id {
padding: 6px 10px;
margin-bottom: 12px;
.model-id-label {
font-size: 11px;
}
.model-id-value {
font-size: 11px;
}
}
.model-description {
font-size: 13px;
line-height: 1.5;
margin-bottom: 12px;
min-height: auto;
-webkit-line-clamp: 2;
max-height: 3em;
&:hover {
/* 移动端取消悬停展开,或者改为点击展开(这里简单处理为取消悬停效果以免遮挡) */
-webkit-line-clamp: 2;
max-height: 3em;
overflow: hidden;
position: static;
box-shadow: none;
background: transparent;
padding: 0;
}
}
.model-footer {
padding-top: 12px;
gap: 8px;
.model-tags {
gap: 4px;
:deep(.el-tag) {
height: 20px;
padding: 0 6px;
font-size: 10px;
}
}
.model-pricing {
padding: 4px 8px;
.pricing-label {
display: none; // 移动端隐藏"计费倍率"文字,只显示数字
}
.pricing-value {
font-size: 14px;
}
}
}
}
}
}
}
}
}
}
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
</style>

View File

@@ -7,6 +7,7 @@ interface ImportMetaEnv {
readonly VITE_WEB_BASE_API: string;
readonly VITE_API_URL: string;
readonly VITE_FILE_UPLOAD_API: string;
readonly VITE_BUILD_COMPRESS: string;
readonly VITE_SSO_SEVER_URL: string;
readonly VITE_APP_VERSION: string;
}