fix(ui): 修复移动端卡片 Vue 结构和显示逻辑

- 恢复 clean 版本后重新添加移动端适配
- 修正 methods 结构,移除重复方法
- 移除内联 display:none,用纯 CSS 控制
- 添加 getStatusType 方法供卡片使用
This commit is contained in:
lt
2026-04-27 19:57:05 +08:00
parent 54c84b6681
commit 4647921e01
+6 -21
View File
@@ -36,18 +36,12 @@
.content-area { padding: 16px; padding-bottom: 80px; } .content-area { padding: 16px; padding-bottom: 80px; }
} }
/* 移动端表格优化 */ /* 移动端卡片布局 */
@media (max-width: 768px) { @media (max-width: 768px) {
.el-table { font-size: 12px; } .el-table { font-size: 12px; display: none; }
.el-table .el-button { padding: 4px 8px; font-size: 11px; min-height: auto; } .el-table .el-button { padding: 4px 8px; font-size: 11px; min-height: auto; }
.el-table .cell { padding: 0 4px; } .el-table .cell { padding: 0 4px; }
.el-table .el-table__cell { padding: 6px 0; } .el-table .el-table__cell { padding: 6px 0; }
}
/* 移动端卡片列表 */
.topic-card-list { display: none; }
@media (max-width: 768px) {
.table-container { display: none; }
.topic-card-list { display: block; margin: 0 -16px; } .topic-card-list { display: block; margin: 0 -16px; }
.topic-card { .topic-card {
background: white; background: white;
@@ -81,6 +75,7 @@
border-top: 1px solid #ebeef5; border-top: 1px solid #ebeef5;
} }
.topic-card-actions .el-button { flex: 1; min-width: 60px; } .topic-card-actions .el-button { flex: 1; min-width: 60px; }
.mobile-nav { display: flex; }
} }
</style> </style>
</head> </head>
@@ -121,8 +116,7 @@
<el-tag size="large" :type="filterStatus === '已发布' ? 'primary' : ''" @click="filterStatus = '已发布'">已发布 ({{ countByStatus('已发布') }})</el-tag> <el-tag size="large" :type="filterStatus === '已发布' ? 'primary' : ''" @click="filterStatus = '已发布'">已发布 ({{ countByStatus('已发布') }})</el-tag>
</div> </div>
<div class="card" style="width: 100%; overflow-x: auto; padding: 16px;"> <div class="card" style="width: 100%; overflow-x: auto; padding: 16px;">
<el-table :data="filteredTopics" stripe v-loading="loadingTable" @selection-change="selectedTopicIds = $event" :cell-class-name="getMobileCellClass"> <el-table :data="filteredTopics" stripe v-loading="loadingTable" @selection-change="selectedTopicIds = $event">
<el-table-column type="selection" width="55"></el-table-column> <el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="ID" width="70" fixed></el-table-column> <el-table-column prop="id" label="ID" width="70" fixed></el-table-column>
<el-table-column prop="title" label="标题" min-width="200"></el-table-column> <el-table-column prop="title" label="标题" min-width="200"></el-table-column>
@@ -136,7 +130,7 @@
<el-table-column prop="created_at" label="创建时间" width="140"><template #default="scope">{{ formatDate(scope.row.created_at) }}</template></el-table-column> <el-table-column prop="created_at" label="创建时间" width="140"><template #default="scope">{{ formatDate(scope.row.created_at) }}</template></el-table-column>
<el-table-column prop="generated_at" label="创作时间" width="140"><template #default="scope">{{ scope.row.generated_at ? formatDate(scope.row.generated_at) : '-' }}</template></el-table-column> <el-table-column prop="generated_at" label="创作时间" width="140"><template #default="scope">{{ scope.row.generated_at ? formatDate(scope.row.generated_at) : '-' }}</template></el-table-column>
<el-table-column prop="published_at" label="发布时间" width="140"><template #default="scope">{{ scope.row.published_at ? formatDate(scope.row.published_at) : '-' }}</template></el-table-column> <el-table-column prop="published_at" label="发布时间" width="140"><template #default="scope">{{ scope.row.published_at ? formatDate(scope.row.published_at) : '-' }}</template></el-table-column>
<el-table-column label="操作" width="220" fixed="right"> <el-table-column label="操作" width="280" fixed="right">
<template #default="scope"> <template #default="scope">
<div style="display: flex; gap: 4px; flex-wrap: wrap;"> <div style="display: flex; gap: 4px; flex-wrap: wrap;">
<el-button size="small" @click="openPreview(scope.row)" type="primary">预览</el-button> <el-button size="small" @click="openPreview(scope.row)" type="primary">预览</el-button>
@@ -163,7 +157,6 @@
<div>创建: {{ formatDate(topic.created_at) }}</div> <div>创建: {{ formatDate(topic.created_at) }}</div>
<div>创作: {{ topic.generated_at ? formatDate(topic.generated_at) : '-' }}</div> <div>创作: {{ topic.generated_at ? formatDate(topic.generated_at) : '-' }}</div>
<div>发布: {{ topic.published_at ? formatDate(topic.published_at) : '-' }}</div> <div>发布: {{ topic.published_at ? formatDate(topic.published_at) : '-' }}</div>
<div>今日: {{ topic.is_today ? '是' : '否' }}</div>
</div> </div>
<div class="topic-card-actions"> <div class="topic-card-actions">
<el-button size="small" @click="openPreview(topic)" type="primary">预览</el-button> <el-button size="small" @click="openPreview(topic)" type="primary">预览</el-button>
@@ -255,15 +248,7 @@
.then(response => response.ok ? response.json() : Promise.reject()) .then(response => response.ok ? response.json() : Promise.reject())
.then(data => { this.currentUser = data.user; this.isAdmin = data.user.role === 'admin'; this.isLoggedIn = true; this.fetchTopics(); }) .then(data => { this.currentUser = data.user; this.isAdmin = data.user.role === 'admin'; this.isLoggedIn = true; this.fetchTopics(); })
.catch(() => { localStorage.removeItem('authToken'); window.location.href = '/'; }); .catch(() => { localStorage.removeItem('authToken'); window.location.href = '/'; });
, }
getStatusType(status) {
const map = { '待处理': 'warning', '待审查': 'danger', '待发布': 'success', '已发布': 'info' };
return map[status] || 'primary';
},
getMobileCellClass({ row, column }) {
// 移动端隐藏部分列的逻辑在 CSS 中处理
return '';
} }
}; };
const app = Vue.createApp(TopicsApp); const app = Vue.createApp(TopicsApp);
app.use(ElementPlus); app.use(ElementPlus);