This commit is contained in:
jianzhichu
2026-02-06 23:17:50 +08:00
parent c1d5db18a9
commit 8b98abc94d
17 changed files with 268 additions and 126 deletions
+6 -2
View File
@@ -15,7 +15,7 @@
</a-button>
<transition name="search-input-fade">
<div v-if="searchInputVisible" class="search-input-wrapper">
<a-input v-model:value="quaryData.followUserName" placeholder="输入关注的用户名,按回车" allow-clear @pressEnter="handleSearch" class="search-input" ref="searchInputRef" />
<a-input v-model:value="quaryData.followUserName" placeholder="输入博主用户名或抖音号,按回车" allow-clear @pressEnter="handleSearch" class="search-input" ref="searchInputRef" />
</div>
</transition>
<a-button type="primary" class="sync-btn" @click="handleAdd" :disabled="isAddDisabled">
@@ -51,7 +51,7 @@
</div>
<div class="card-content">
<div class="card-name">
{{ item.uperName }}
{{ item.uperName }} <span style="font-size:12px;">{{item.douyinNo?`(${item.douyinNo})`:''}}</span>
<!-- 非关注小标记 -->
<span v-if="item.isNoFollowed" class="no-followed-badge">非关注</span>
<!-- 删除按钮仅非关注项显示放在名字+非关注后面v-if="item.isNoFollowed" -->
@@ -183,6 +183,7 @@ interface FollowItem {
isEditing: boolean;
isSaving?: boolean;
uperId?: string; // 原userId改为uperId
douyinNo?: string;
isNoFollowed: boolean; // 新增:是否为非关注博主
}
@@ -201,6 +202,7 @@ interface AddForm {
fullSync: boolean;
mySelfId: string;
uperId: string;
douyinNo: string;
}
// Tab列表数据
@@ -233,6 +235,7 @@ const addForm = ref<AddForm>({
fullSync: false,
mySelfId: '',
uperId: '',
douyinNo: '',
});
// 表单校验规则
@@ -543,6 +546,7 @@ const handleAdd = () => {
fullSync: false,
secUid: '',
mySelfId: activeTabKey.value,
douyinNo: '',
};
// 清空错误信息
Object.keys(addFormErrors.value).forEach((key) => {
+113 -22
View File
@@ -62,6 +62,34 @@
<span class="subitem-meta">图文视频 <span class="subitem-count">({{ graphicVideoCount }})</span></span>
<span class="subitem-size">{{ graphicVideoSize }}G</span>
</div>
<!-- 新增合集视频统计项 -->
<div class="subitem" :title="`合集视频数: ${mixCount || 0} (占用: ${videoMixSize}G)`">
<div class="subitem-icon mix-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path>
</svg>
</div>
<span class="subitem-meta">合集视频 <span class="subitem-count">({{ mixCount || 0 }})</span></span>
<span class="subitem-size">{{ videoMixSize }}G</span>
</div>
<!-- 新增短剧视频统计项 -->
<div class="subitem" :title="`短剧视频数: ${seriesCount || 0} (占用: ${videoSeriesSize}G)`">
<div class="subitem-icon series-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="2" y="2" width="20" height="20" rx="2.18" ry="2.18"></rect>
<line x1="7" y1="2" x2="7" y2="22"></line>
<line x1="17" y1="2" x2="17" y2="22"></line>
<line x1="2" y1="12" x2="22" y2="12"></line>
<line x1="2" y1="7" x2="7" y2="7"></line>
<line x1="2" y1="17" x2="7" y2="17"></line>
<line x1="17" y1="17" x2="22" y2="17"></line>
<line x1="17" y1="7" x2="22" y2="7"></line>
</svg>
</div>
<span class="subitem-meta">短剧视频 <span class="subitem-count">({{ seriesCount || 0 }})</span></span>
<span class="subitem-size">{{ videoSeriesSize }}G</span>
</div>
</div>
</div>
@@ -126,15 +154,17 @@
<div v-if="activeTab === 'follow'" class="tab-content follow-tab">
<!-- 搜索+操作栏移动端单行布局适配小屏 -->
<div class="follow-header">
<!-- <a-select v-model:value="filterStatus" class="follow-filter-select" placeholder="筛选同步状态" @change="handleFilterChange">
<a-option value="all">全部</a-option>
<a-option value="openSync">已开启同步</a-option>
<a-option value="fullSync">全量同步</a-option>
<a-option value="closeSync">未开启同步</a-option>
</a-select> -->
<div class="search-wrapper">
<a-input v-model:value="quaryData.followUserName" placeholder="搜索博主名称" allow-clear @pressEnter="handleSearch" class="follow-search-input" @input="searchInputVisible = quaryData.followUserName && quaryData.followUserName.trim() !== ''" />
<a-input v-model:value="quaryData.followUserName" placeholder="搜索博主名称或抖音号" allow-clear @pressEnter="handleSearch" @search="handleSearch" class="follow-search-input" />
</div>
<div class="follow-actions">
<!-- 新增搜索按钮和同步按钮同排 -->
<a-button type="default" class="follow-btn search-btn" @click="handleSearch" :disabled="!quaryData.followUserName || quaryData.followUserName.trim() === ''">
<SearchOutlined />
</a-button>
<!-- 原有同步按钮 -->
<a-button type="primary" class="follow-btn sync-btn" @click="handleSyncAll" :disabled="isSyncDisabled">
<SyncOutlined />
</a-button>
@@ -165,8 +195,9 @@
</div>
<div class="name-actions">
<div class="name-wrapper">
<h3 class="uper-name">{{ truncateText(item.uperName, 10) || '未知博主' }}</h3> <!-- 增加空值处理 -->
<h3 class="uper-name">{{ truncateText(item.uperName, 10) || '未知博主' }}<span style="font-size:12px;margin-left:5px;">{{item.douyinNo?`(${item.douyinNo})`:''}}</span></h3> <!-- 增加空值处理 -->
<span v-if="item.isNoFollowed" class="no-followed-badge">非关注</span>
</div>
<div class="top-actions">
<!-- 删除按钮仅非关注显示 -->
@@ -387,6 +418,7 @@ interface FollowItem {
isEditing: boolean;
isSaving?: boolean;
uperId?: string;
douyinNo?: string;
isNoFollowed: boolean;
}
interface QuaryParam {
@@ -402,10 +434,14 @@ const favoriteCount = ref<number>(0);
const collectCount = ref<number>(0);
const followCount = ref<number>(0);
const graphicVideoCount = ref<number>(0);
const mixCount = ref<number>(0);
const seriesCount = ref<number>(0);
const favoriteSize = ref<string>('0.00');
const collectSize = ref<string>('0.00');
const followSize = ref<string>('0.00');
const graphicVideoSize = ref<string>('0.00');
const videoMixSize = ref<string>('0.00');
const videoSeriesSize = ref<string>('0.00');
const activeTab = ref<string>('dashboard');
const logFilter = ref<string>('all');
const logs = ref<LogItem[]>([]);
@@ -432,7 +468,6 @@ const followData = ref<FollowItem[]>([]);
const loading = ref(false);
const noMoreData = ref(false);
const hasMore = ref(true);
const searchInputVisible = ref(false);
const isSyncDisabled = ref(false);
const isAddDisabled = ref(false);
@@ -489,22 +524,27 @@ watch(
}
);
// ========== 原有仪表盘方法 ==========
const loadDashboardData = async () => {
try {
const res = await useApiStore().VideoStatics();
totalVideos.value = res.data.videoCount;
fileSizeTotal.value = res.data.videoSizeTotal || '0.00';
favoriteCount.value = res.data.favoriteCount;
collectCount.value = res.data.collectCount;
followCount.value = res.data.followCount || 0;
graphicVideoCount.value = res.data.graphicVideoCount || 0;
mixCount.value = res.data.mixCount || 0;
seriesCount.value = res.data.seriesCount || 0;
favoriteSize.value = res.data.videoFavoriteSize || '0.00';
collectSize.value = res.data.videoCollectSize || '0.00';
followSize.value = res.data.videoFollowSize || '0.00';
graphicVideoSize.value = res.data.graphicVideoSize || '0.00';
videoMixSize.value = res.data.videoMixSize || '0.00';
videoSeriesSize.value = res.data.videoSeriesSize || '0.00';
} catch (err) {
console.error('加载移动端仪表盘数据失败:', err);
console.error('加载仪表盘数据失败:', err);
}
};
const loadLogData = async () => {
@@ -893,7 +933,6 @@ const handleDeleteItem = (item: FollowItem) => {
};
</script>
<!-- 全局样式 -->
<style>
html,
body {
@@ -920,6 +959,25 @@ body {
.ant-card-body {
padding: 0 !important;
}
/* ========== 移动端隐藏所有滚动条 - 核心代码 ========== */
/* 针对webkit内核浏览器(iOS/安卓Chrome/Edge等) */
*::-webkit-scrollbar {
width: 0px !important; /* 垂直滚动条宽度 */
height: 0px !important; /* 水平滚动条高度 */
display: none !important; /* 直接隐藏滚动条元素 */
}
/* 滚动条轨道/滑块也隐藏,防止残留 */
*::-webkit-scrollbar-track,
*::-webkit-scrollbar-thumb {
background: transparent !important;
border-radius: 0 !important;
}
/* 火狐浏览器适配(可选,移动端火狐占比极低) */
* {
scrollbar-width: none !important; /* 火狐隐藏滚动条 */
-ms-overflow-style: none !important; /* IE/Edge 隐藏滚动条 */
}
</style>
<style scoped>
@@ -1634,12 +1692,6 @@ body {
font-size: 14px !important;
width: 100% !important;
}
/* 搜索图标定位 */
.search-wrapper :deep(.ant-input-suffix) {
right: 12px !important;
top: 50% !important;
transform: translateY(-50%) !important;
}
.follow-actions {
display: flex;
gap: 8px;
@@ -1654,11 +1706,6 @@ body {
align-items: center !important;
justify-content: center !important;
}
.add-btn {
background-color: #4caf50 !important;
border-color: #4caf50 !important;
}
/* Tab导航:横向滚动 */
.follow-tab-wrapper {
width: 100%;
@@ -2194,4 +2241,48 @@ html.dark-mode .avatar-placeholder {
font-size: 12px !important;
}
}
/* 筛选下拉选择器:和搜索框、同步按钮统一风格,移动端适配 */
.follow-filter-select {
width: 120px !important;
height: 40px !important;
flex-shrink: 0;
}
/* 覆盖antd select默认样式,和布局匹配 */
:deep(.follow-filter-select .ant-select-selector) {
height: 100% !important;
border-radius: 20px !important; /* 和搜索框同圆角,视觉统一 */
display: flex !important;
align-items: center !important;
padding: 0 12px !important;
font-size: 13px !important;
}
/* 隐藏select默认边框高亮(可选,更简洁) */
:deep(.follow-filter-select .ant-select-focused .ant-select-selector) {
box-shadow: none !important;
border-color: #d9d9d9 !important;
}
/* 下拉选项弹窗:适配移动端,调大宽度 */
:deep(.follow-filter-select .ant-select-dropdown) {
min-width: 120px !important;
font-size: 13px !important;
}
/* 黑暗模式适配:筛选选择器样式统一 */
html.dark-mode :deep(.follow-filter-select .ant-select-selector) {
background-color: #1f4068 !important;
border-color: rgba(255, 255, 255, 0.1) !important;
color: #e0e0e0 !important;
}
html.dark-mode :deep(.follow-filter-select .ant-select-dropdown) {
background-color: #1e1e3f !important;
border-color: rgba(255, 255, 255, 0.1) !important;
}
html.dark-mode :deep(.follow-filter-select .ant-select-item) {
color: #e0e0e0 !important;
}
html.dark-mode :deep(.follow-filter-select .ant-select-item-selected) {
background-color: #4caf50 !important;
color: #fff !important;
}
</style>
+2 -2
View File
@@ -97,7 +97,7 @@
</span>
</div>
</a-form-item> -->
<a-form-item v-if="formState.DownImageVideo" has-feedback label="保留音频" name="DownMp3" :wrapper-col="{ span: 20 }">
<a-form-item has-feedback label="保留音频" name="DownMp3" :wrapper-col="{ span: 20 }">
<a-switch v-model:checked="formState.DownMp3" />
<div class="flex items-start mt-1 text-sm text-gray-500">
<InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" />
@@ -105,7 +105,7 @@
</div>
</a-form-item>
<a-form-item v-if="formState.DownImageVideo" has-feedback label="保留图片" name="DownImage" :wrapper-col="{ span: 20 }">
<a-form-item has-feedback label="保留图片" name="DownImage" :wrapper-col="{ span: 20 }">
<a-switch v-model:checked="formState.DownImage" />
<div class="flex items-start mt-1 text-sm text-gray-500">
<InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" />