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
+1 -1
View File
@@ -17,6 +17,6 @@
<SelfContained>false</SelfContained> <SelfContained>false</SelfContained>
<!--<DockerArch>x86</DockerArch>--> <!--<DockerArch>x86</DockerArch>-->
<!--<DockerArch>arm</DockerArch> --> <!--<DockerArch>arm</DockerArch> -->
<!--<DockerCoreVersion>2.1.0</DockerCoreVersion>--> <!--<DockerCoreVersion>2.1.1</DockerCoreVersion>-->
</PropertyGroup> </PropertyGroup>
</Project> </Project>
@@ -3,7 +3,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\</_PublishTargetUrl> <_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2026-02-02T15:24:09.9134119Z||;True|2026-02-02T23:21:52.3235946+08:00||;False|2026-02-02T23:21:47.1386702+08:00||;True|2026-02-02T23:20:46.6277206+08:00||;False|2026-02-02T23:20:40.3158947+08:00||;True|2026-02-02T22:55:39.4268475+08:00||;True|2026-02-01T21:34:30.5989260+08:00||;True|2026-02-01T21:30:20.7556066+08:00||;True|2026-01-30T21:56:47.1840381+08:00||;True|2026-01-28T22:01:00.8412391+08:00||;False|2026-01-28T21:49:29.1242233+08:00||;True|2026-01-28T21:48:26.1707204+08:00||;True|2026-01-28T21:48:05.8291762+08:00||;False|2026-01-28T21:48:01.1596391+08:00||;True|2026-01-28T21:37:59.4831763+08:00||;False|2026-01-28T21:37:53.5855464+08:00||;True|2026-01-28T21:27:51.1872828+08:00||;True|2026-01-28T13:01:14.1677037+08:00||;True|2026-01-28T12:36:45.7819776+08:00||;True|2026-01-28T12:09:15.6540204+08:00||;True|2026-01-28T12:08:40.0490617+08:00||;True|2026-01-28T11:58:55.4078870+08:00||;True|2026-01-27T22:37:03.3304942+08:00||;True|2026-01-27T22:05:40.4316281+08:00||;True|2026-01-26T22:30:43.5083924+08:00||;False|2026-01-26T22:30:33.7355213+08:00||;True|2026-01-26T22:26:26.0218548+08:00||;True|2026-01-26T22:21:32.3171217+08:00||;True|2026-01-26T22:20:40.3916780+08:00||;True|2026-01-26T22:16:19.1017273+08:00||;True|2026-01-26T22:13:34.2028883+08:00||;True|2026-01-26T21:46:23.7117812+08:00||;True|2026-01-26T21:41:19.6963033+08:00||;True|2026-01-25T21:27:13.9893777+08:00||;True|2026-01-24T21:45:22.8493624+08:00||;True|2026-01-24T21:31:35.4635265+08:00||;True|2026-01-24T21:27:31.3098506+08:00||;True|2026-01-24T15:47:01.6934638+08:00||;True|2026-01-24T15:32:35.6316009+08:00||;True|2026-01-24T15:16:28.7216639+08:00||;True|2026-01-23T22:14:26.8066324+08:00||;True|2026-01-23T13:36:48.4086406+08:00||;True|2026-01-23T13:30:27.2924204+08:00||;True|2026-01-23T13:02:53.3219368+08:00||;True|2026-01-23T13:01:54.3466638+08:00||;True|2026-01-23T13:01:28.8560809+08:00||;True|2026-01-22T23:18:32.0400436+08:00||;True|2026-01-22T22:29:29.5746209+08:00||;True|2026-01-22T21:32:21.7284081+08:00||;True|2026-01-22T21:20:26.5985955+08:00||;False|2026-01-22T21:20:21.1372539+08:00||;True|2026-01-22T21:11:18.3771739+08:00||;True|2026-01-22T20:58:55.9862778+08:00||;True|2026-01-22T20:51:48.6699461+08:00||;False|2026-01-22T20:51:42.2079210+08:00||;True|2026-01-22T20:50:34.7280114+08:00||;True|2026-01-22T20:50:11.1588492+08:00||;True|2026-01-22T16:11:14.0626037+08:00||;True|2026-01-22T15:53:16.6377347+08:00||;True|2026-01-22T15:45:34.0935091+08:00||;True|2026-01-22T12:44:28.1577014+08:00||;True|2026-01-22T12:40:45.7449335+08:00||;True|2026-01-22T12:39:07.0683214+08:00||;True|2026-01-22T09:55:49.7086190+08:00||;True|2026-01-22T01:37:53.6972395+08:00||;True|2026-01-22T01:34:14.2142463+08:00||;True|2026-01-22T01:32:50.9228911+08:00||;True|2026-01-22T01:29:43.8871986+08:00||;True|2026-01-22T01:29:40.7838709+08:00||;True|2026-01-22T01:27:34.4763970+08:00||;True|2026-01-22T01:26:55.0117367+08:00||;True|2026-01-22T01:23:19.4789587+08:00||;True|2026-01-19T10:19:44.8997385+08:00||;True|2026-01-19T10:11:10.2305307+08:00||;True|2026-01-17T00:52:08.8180346+08:00||;False|2026-01-17T00:52:03.1829000+08:00||;True|2026-01-17T00:45:04.0498090+08:00||;True|2026-01-16T21:00:57.7239379+08:00||;True|2026-01-16T21:00:03.3912989+08:00||;True|2026-01-16T20:56:08.5505592+08:00||;True|2026-01-16T20:46:32.3067302+08:00||;True|2026-01-15T22:18:57.9835738+08:00||;True|2026-01-15T22:07:25.4753938+08:00||;True|2026-01-15T22:07:14.8243754+08:00||;True|2026-01-15T21:40:13.2613927+08:00||;True|2026-01-15T20:57:56.6291682+08:00||;True|2026-01-15T20:57:47.1363536+08:00||;True|2026-01-15T20:08:44.4710883+08:00||;True|2026-01-15T20:04:51.8284314+08:00||;False|2026-01-15T20:04:45.3258155+08:00||;True|2026-01-15T19:59:11.7907672+08:00||;True|2026-01-15T01:10:48.9066941+08:00||;True|2026-01-15T01:03:23.6216975+08:00||;True|2026-01-15T01:03:16.3364591+08:00||;False|2026-01-15T01:03:10.5654436+08:00||;True|2026-01-15T00:49:21.6559622+08:00||;True|2026-01-15T00:10:42.7288439+08:00||;True|2026-01-15T00:06:28.4241682+08:00||;True|2026-01-13T22:34:15.2372411+08:00||;True|2026-01-13T22:26:46.4522947+08:00||;</History> <History>True|2026-02-06T15:15:19.0037070Z||;True|2026-02-06T22:52:30.1006808+08:00||;True|2026-02-06T22:49:02.0056235+08:00||;True|2026-02-06T22:45:30.6355735+08:00||;False|2026-02-06T22:45:25.7210123+08:00||;True|2026-02-06T22:38:37.6994272+08:00||;True|2026-02-06T22:14:47.8146805+08:00||;True|2026-02-03T22:34:12.3588819+08:00||;True|2026-02-03T22:20:08.9945012+08:00||;True|2026-02-03T21:06:17.7655312+08:00||;True|2026-02-02T23:24:09.9134119+08:00||;True|2026-02-02T23:21:52.3235946+08:00||;False|2026-02-02T23:21:47.1386702+08:00||;True|2026-02-02T23:20:46.6277206+08:00||;False|2026-02-02T23:20:40.3158947+08:00||;True|2026-02-02T22:55:39.4268475+08:00||;True|2026-02-01T21:34:30.5989260+08:00||;True|2026-02-01T21:30:20.7556066+08:00||;True|2026-01-30T21:56:47.1840381+08:00||;True|2026-01-28T22:01:00.8412391+08:00||;False|2026-01-28T21:49:29.1242233+08:00||;True|2026-01-28T21:48:26.1707204+08:00||;True|2026-01-28T21:48:05.8291762+08:00||;False|2026-01-28T21:48:01.1596391+08:00||;True|2026-01-28T21:37:59.4831763+08:00||;False|2026-01-28T21:37:53.5855464+08:00||;True|2026-01-28T21:27:51.1872828+08:00||;True|2026-01-28T13:01:14.1677037+08:00||;True|2026-01-28T12:36:45.7819776+08:00||;True|2026-01-28T12:09:15.6540204+08:00||;True|2026-01-28T12:08:40.0490617+08:00||;True|2026-01-28T11:58:55.4078870+08:00||;True|2026-01-27T22:37:03.3304942+08:00||;True|2026-01-27T22:05:40.4316281+08:00||;True|2026-01-26T22:30:43.5083924+08:00||;False|2026-01-26T22:30:33.7355213+08:00||;True|2026-01-26T22:26:26.0218548+08:00||;True|2026-01-26T22:21:32.3171217+08:00||;True|2026-01-26T22:20:40.3916780+08:00||;True|2026-01-26T22:16:19.1017273+08:00||;True|2026-01-26T22:13:34.2028883+08:00||;True|2026-01-26T21:46:23.7117812+08:00||;True|2026-01-26T21:41:19.6963033+08:00||;True|2026-01-25T21:27:13.9893777+08:00||;True|2026-01-24T21:45:22.8493624+08:00||;True|2026-01-24T21:31:35.4635265+08:00||;True|2026-01-24T21:27:31.3098506+08:00||;True|2026-01-24T15:47:01.6934638+08:00||;True|2026-01-24T15:32:35.6316009+08:00||;True|2026-01-24T15:16:28.7216639+08:00||;True|2026-01-23T22:14:26.8066324+08:00||;True|2026-01-23T13:36:48.4086406+08:00||;True|2026-01-23T13:30:27.2924204+08:00||;True|2026-01-23T13:02:53.3219368+08:00||;True|2026-01-23T13:01:54.3466638+08:00||;True|2026-01-23T13:01:28.8560809+08:00||;True|2026-01-22T23:18:32.0400436+08:00||;True|2026-01-22T22:29:29.5746209+08:00||;True|2026-01-22T21:32:21.7284081+08:00||;True|2026-01-22T21:20:26.5985955+08:00||;False|2026-01-22T21:20:21.1372539+08:00||;True|2026-01-22T21:11:18.3771739+08:00||;True|2026-01-22T20:58:55.9862778+08:00||;True|2026-01-22T20:51:48.6699461+08:00||;False|2026-01-22T20:51:42.2079210+08:00||;True|2026-01-22T20:50:34.7280114+08:00||;True|2026-01-22T20:50:11.1588492+08:00||;True|2026-01-22T16:11:14.0626037+08:00||;True|2026-01-22T15:53:16.6377347+08:00||;True|2026-01-22T15:45:34.0935091+08:00||;True|2026-01-22T12:44:28.1577014+08:00||;True|2026-01-22T12:40:45.7449335+08:00||;True|2026-01-22T12:39:07.0683214+08:00||;True|2026-01-22T09:55:49.7086190+08:00||;True|2026-01-22T01:37:53.6972395+08:00||;True|2026-01-22T01:34:14.2142463+08:00||;True|2026-01-22T01:32:50.9228911+08:00||;True|2026-01-22T01:29:43.8871986+08:00||;True|2026-01-22T01:29:40.7838709+08:00||;True|2026-01-22T01:27:34.4763970+08:00||;True|2026-01-22T01:26:55.0117367+08:00||;True|2026-01-22T01:23:19.4789587+08:00||;True|2026-01-19T10:19:44.8997385+08:00||;True|2026-01-19T10:11:10.2305307+08:00||;True|2026-01-17T00:52:08.8180346+08:00||;False|2026-01-17T00:52:03.1829000+08:00||;True|2026-01-17T00:45:04.0498090+08:00||;True|2026-01-16T21:00:57.7239379+08:00||;True|2026-01-16T21:00:03.3912989+08:00||;True|2026-01-16T20:56:08.5505592+08:00||;True|2026-01-16T20:46:32.3067302+08:00||;True|2026-01-15T22:18:57.9835738+08:00||;True|2026-01-15T22:07:25.4753938+08:00||;True|2026-01-15T22:07:14.8243754+08:00||;True|2026-01-15T21:40:13.2613927+08:00||;True|2026-01-15T20:57:56.6291682+08:00||;True|2026-01-15T20:57:47.1363536+08:00||;True|2026-01-15T20:08:44.4710883+08:00||;True|2026-01-15T20:04:51.8284314+08:00||;False|2026-01-15T20:04:45.3258155+08:00||;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
</Project> </Project>
+3 -3
View File
@@ -95,8 +95,8 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
| 镜像标签 | 架构 | | 镜像标签 | 架构 |
| ----------------- | -------------- | | ----------------- | -------------- |
| `beta_2.1.0` | x86_64 (amd64) | | `beta_2.1.1` | x86_64 (amd64) |
| `arm_2.1.0` | ARM64 | | `arm_2.1.1` | ARM64 |
### 构建命令示例 ### 构建命令示例
@@ -113,7 +113,7 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
services: services:
dysync: dysync:
image: ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_2.1.0 image: ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_2.1.1
container_name: dysync2026 # 容器名称 container_name: dysync2026 # 容器名称
restart: unless-stopped # 始终重启容器,除非容器被手动停止或Docker服务停止 restart: unless-stopped # 始终重启容器,除非容器被手动停止或Docker服务停止
ports: ports:
+6 -2
View File
@@ -15,7 +15,7 @@
</a-button> </a-button>
<transition name="search-input-fade"> <transition name="search-input-fade">
<div v-if="searchInputVisible" class="search-input-wrapper"> <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> </div>
</transition> </transition>
<a-button type="primary" class="sync-btn" @click="handleAdd" :disabled="isAddDisabled"> <a-button type="primary" class="sync-btn" @click="handleAdd" :disabled="isAddDisabled">
@@ -51,7 +51,7 @@
</div> </div>
<div class="card-content"> <div class="card-content">
<div class="card-name"> <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> <span v-if="item.isNoFollowed" class="no-followed-badge">非关注</span>
<!-- 删除按钮仅非关注项显示放在名字+非关注后面v-if="item.isNoFollowed" --> <!-- 删除按钮仅非关注项显示放在名字+非关注后面v-if="item.isNoFollowed" -->
@@ -183,6 +183,7 @@ interface FollowItem {
isEditing: boolean; isEditing: boolean;
isSaving?: boolean; isSaving?: boolean;
uperId?: string; // 原userId改为uperId uperId?: string; // 原userId改为uperId
douyinNo?: string;
isNoFollowed: boolean; // 新增:是否为非关注博主 isNoFollowed: boolean; // 新增:是否为非关注博主
} }
@@ -201,6 +202,7 @@ interface AddForm {
fullSync: boolean; fullSync: boolean;
mySelfId: string; mySelfId: string;
uperId: string; uperId: string;
douyinNo: string;
} }
// Tab列表数据 // Tab列表数据
@@ -233,6 +235,7 @@ const addForm = ref<AddForm>({
fullSync: false, fullSync: false,
mySelfId: '', mySelfId: '',
uperId: '', uperId: '',
douyinNo: '',
}); });
// 表单校验规则 // 表单校验规则
@@ -543,6 +546,7 @@ const handleAdd = () => {
fullSync: false, fullSync: false,
secUid: '', secUid: '',
mySelfId: activeTabKey.value, mySelfId: activeTabKey.value,
douyinNo: '',
}; };
// 清空错误信息 // 清空错误信息
Object.keys(addFormErrors.value).forEach((key) => { 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-meta">图文视频 <span class="subitem-count">({{ graphicVideoCount }})</span></span>
<span class="subitem-size">{{ graphicVideoSize }}G</span> <span class="subitem-size">{{ graphicVideoSize }}G</span>
</div> </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>
</div> </div>
@@ -126,15 +154,17 @@
<div v-if="activeTab === 'follow'" class="tab-content follow-tab"> <div v-if="activeTab === 'follow'" class="tab-content follow-tab">
<!-- 搜索+操作栏移动端单行布局适配小屏 --> <!-- 搜索+操作栏移动端单行布局适配小屏 -->
<div class="follow-header"> <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"> <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>
<div class="follow-actions"> <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"> <a-button type="primary" class="follow-btn sync-btn" @click="handleSyncAll" :disabled="isSyncDisabled">
<SyncOutlined /> <SyncOutlined />
</a-button> </a-button>
@@ -165,8 +195,9 @@
</div> </div>
<div class="name-actions"> <div class="name-actions">
<div class="name-wrapper"> <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> <span v-if="item.isNoFollowed" class="no-followed-badge">非关注</span>
</div> </div>
<div class="top-actions"> <div class="top-actions">
<!-- 删除按钮仅非关注显示 --> <!-- 删除按钮仅非关注显示 -->
@@ -387,6 +418,7 @@ interface FollowItem {
isEditing: boolean; isEditing: boolean;
isSaving?: boolean; isSaving?: boolean;
uperId?: string; uperId?: string;
douyinNo?: string;
isNoFollowed: boolean; isNoFollowed: boolean;
} }
interface QuaryParam { interface QuaryParam {
@@ -402,10 +434,14 @@ const favoriteCount = ref<number>(0);
const collectCount = ref<number>(0); const collectCount = ref<number>(0);
const followCount = ref<number>(0); const followCount = ref<number>(0);
const graphicVideoCount = 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 favoriteSize = ref<string>('0.00');
const collectSize = ref<string>('0.00'); const collectSize = ref<string>('0.00');
const followSize = ref<string>('0.00'); const followSize = ref<string>('0.00');
const graphicVideoSize = 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 activeTab = ref<string>('dashboard');
const logFilter = ref<string>('all'); const logFilter = ref<string>('all');
const logs = ref<LogItem[]>([]); const logs = ref<LogItem[]>([]);
@@ -432,7 +468,6 @@ const followData = ref<FollowItem[]>([]);
const loading = ref(false); const loading = ref(false);
const noMoreData = ref(false); const noMoreData = ref(false);
const hasMore = ref(true); const hasMore = ref(true);
const searchInputVisible = ref(false);
const isSyncDisabled = ref(false); const isSyncDisabled = ref(false);
const isAddDisabled = ref(false); const isAddDisabled = ref(false);
@@ -489,22 +524,27 @@ watch(
} }
); );
// ========== 原有仪表盘方法 ==========
const loadDashboardData = async () => { const loadDashboardData = async () => {
try { try {
const res = await useApiStore().VideoStatics(); const res = await useApiStore().VideoStatics();
totalVideos.value = res.data.videoCount; totalVideos.value = res.data.videoCount;
fileSizeTotal.value = res.data.videoSizeTotal || '0.00'; fileSizeTotal.value = res.data.videoSizeTotal || '0.00';
favoriteCount.value = res.data.favoriteCount; favoriteCount.value = res.data.favoriteCount;
collectCount.value = res.data.collectCount; collectCount.value = res.data.collectCount;
followCount.value = res.data.followCount || 0; followCount.value = res.data.followCount || 0;
graphicVideoCount.value = res.data.graphicVideoCount || 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'; favoriteSize.value = res.data.videoFavoriteSize || '0.00';
collectSize.value = res.data.videoCollectSize || '0.00'; collectSize.value = res.data.videoCollectSize || '0.00';
followSize.value = res.data.videoFollowSize || '0.00'; followSize.value = res.data.videoFollowSize || '0.00';
graphicVideoSize.value = res.data.graphicVideoSize || '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) { } catch (err) {
console.error('加载移动端仪表盘数据失败:', err); console.error('加载仪表盘数据失败:', err);
} }
}; };
const loadLogData = async () => { const loadLogData = async () => {
@@ -893,7 +933,6 @@ const handleDeleteItem = (item: FollowItem) => {
}; };
</script> </script>
<!-- 全局样式 -->
<style> <style>
html, html,
body { body {
@@ -920,6 +959,25 @@ body {
.ant-card-body { .ant-card-body {
padding: 0 !important; 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>
<style scoped> <style scoped>
@@ -1634,12 +1692,6 @@ body {
font-size: 14px !important; font-size: 14px !important;
width: 100% !important; width: 100% !important;
} }
/* 搜索图标定位 */
.search-wrapper :deep(.ant-input-suffix) {
right: 12px !important;
top: 50% !important;
transform: translateY(-50%) !important;
}
.follow-actions { .follow-actions {
display: flex; display: flex;
gap: 8px; gap: 8px;
@@ -1654,11 +1706,6 @@ body {
align-items: center !important; align-items: center !important;
justify-content: center !important; justify-content: center !important;
} }
.add-btn {
background-color: #4caf50 !important;
border-color: #4caf50 !important;
}
/* Tab导航:横向滚动 */ /* Tab导航:横向滚动 */
.follow-tab-wrapper { .follow-tab-wrapper {
width: 100%; width: 100%;
@@ -2194,4 +2241,48 @@ html.dark-mode .avatar-placeholder {
font-size: 12px !important; 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> </style>
+2 -2
View File
@@ -97,7 +97,7 @@
</span> </span>
</div> </div>
</a-form-item> --> </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" /> <a-switch v-model:checked="formState.DownMp3" />
<div class="flex items-start mt-1 text-sm text-gray-500"> <div class="flex items-start mt-1 text-sm text-gray-500">
<InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" /> <InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" />
@@ -105,7 +105,7 @@
</div> </div>
</a-form-item> </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" /> <a-switch v-model:checked="formState.DownImage" />
<div class="flex items-start mt-1 text-sm text-gray-500"> <div class="flex items-start mt-1 text-sm text-gray-500">
<InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" /> <InfoCircleOutlined class="text-blue-400 mr-1 mt-0.5" />
+1 -1
View File
@@ -128,7 +128,7 @@
</ItemGroup> </ItemGroup>
</Target> </Target>
<!-- 核心配置:仅用核心版本号2.1.0,自动拼接前缀 --> <!-- 核心配置:仅用核心版本号2.1.1,自动拼接前缀 -->
<!--<Target Name="DockerBuildAndPushAfterPublish" AfterTargets="Publish"> <!--<Target Name="DockerBuildAndPushAfterPublish" AfterTargets="Publish">
<Exec Command="docker build -t jianzhichu/dysync.net:beta_$(DockerCoreVersion) . &amp;&amp; docker tag jianzhichu/dysync.net:beta_$(DockerCoreVersion) ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_$(DockerCoreVersion) &amp;&amp; docker push ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_$(DockerCoreVersion)" <Exec Command="docker build -t jianzhichu/dysync.net:beta_$(DockerCoreVersion) . &amp;&amp; docker tag jianzhichu/dysync.net:beta_$(DockerCoreVersion) ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_$(DockerCoreVersion) &amp;&amp; docker push ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_$(DockerCoreVersion)"
Condition="'$(DockerArch)' == 'x86'" /> Condition="'$(DockerArch)' == 'x86'" />
+1 -1
View File
@@ -2,7 +2,7 @@
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ActiveDebugProfile>dy.net</ActiveDebugProfile> <ActiveDebugProfile>dy.net</ActiveDebugProfile>
<NameOfLastUsedPublishProfile>E:\code\dysync\Properties\PublishProfiles\fn.pubxml</NameOfLastUsedPublishProfile> <NameOfLastUsedPublishProfile>E:\code\dysync\Properties\PublishProfiles\docker.pubxml</NameOfLastUsedPublishProfile>
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID> <Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath> <Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup> </PropertyGroup>
+26 -14
View File
@@ -3,6 +3,7 @@ using dy.net.model.entity;
using dy.net.model.response; using dy.net.model.response;
using dy.net.service; using dy.net.service;
using dy.net.utils; using dy.net.utils;
using System.Threading.Tasks;
namespace dy.net.job namespace dy.net.job
{ {
@@ -39,28 +40,39 @@ namespace dy.net.job
protected override string CreateSaveFolder(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed, DouyinCollectCate cate) protected override string CreateSaveFolder(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed, DouyinCollectCate cate)
{ {
string authorFolder; // 1. 简化获取博主自定义保存路径(合并空值判断)
if (string.IsNullOrWhiteSpace(item.Author?.Nickname) && string.IsNullOrWhiteSpace(item.Author?.Uid)) string saveFolder = !string.IsNullOrWhiteSpace(item?.Author?.Uid)
? base.douyinCommonService.GetDouyinUpSavePath(item.Author.Uid)
: string.Empty;
// 2. 简化博主文件夹命名逻辑
string authorFolder = !string.IsNullOrWhiteSpace(saveFolder)
? saveFolder
: (item?.Author == null || (string.IsNullOrWhiteSpace(item.Author.Nickname) && string.IsNullOrWhiteSpace(item.Author.Uid)))
? "未知博主"
: DouyinFileNameHelper.SanitizeLinuxFileName(item.Author.Nickname, item.Author.Uid, true);
if (string.IsNullOrWhiteSpace(saveFolder)&&!string.IsNullOrEmpty(authorFolder))
{ {
authorFolder = "未知博主"; base.douyinCommonService.SaveDouyinUpSavePath(item.Author.Uid, authorFolder);
}
// 3. 提取重复的视频文件夹名(避免重复调用方法)
string videoFolderName = DouyinFileNameHelper.SanitizeLinuxFileName(item?.Desc, item?.AwemeId, true);
// 4. 简化文件夹路径拼接+存在判断(核心逻辑不变)
string folder = Path.Combine(cookie.SavePath, authorFolder, videoFolderName);
if (Directory.Exists(folder))
{
// 文件夹存在则拼接AwemeId(保留你的原逻辑)
folder = Path.Combine(cookie.SavePath, authorFolder, $"{videoFolderName}_{item.AwemeId}");
} }
else else
{
authorFolder = $"{DouyinFileNameHelper.SanitizeLinuxFileName(item.Author?.Nickname, item.Author?.Uid, true)}";
}
var folder = Path.Combine(cookie.SavePath, authorFolder, $"{DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId, true)}");
if (!Directory.Exists(folder))
{ {
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
} }
else
{
//说明文件夹存在,检查里面有没有文件,如果已经有视频文件了,说明视频标题相同,那么应该重新创建文件夹,+id
folder = Path.Combine(cookie.SavePath, authorFolder , $"{DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId, true)}"+"_" + item.AwemeId);
}
return folder; return folder;
} }
} }
} }
+29 -6
View File
@@ -534,8 +534,6 @@ namespace dy.net.job
// continue; // continue;
//} //}
// 1. 查询数据库中是否已存在该视频(通过 AwemeId 唯一标识)
var exitVideo = await douyinVideoService.GetByAwemeId(item.AwemeId);
//判断视频是否是强制删除且不再下载的视频 //判断视频是否是强制删除且不再下载的视频
var deleteVideo = await douyinCommonService.ExistDeleteVideo(item.AwemeId); var deleteVideo = await douyinCommonService.ExistDeleteVideo(item.AwemeId);
if (deleteVideo) if (deleteVideo)
@@ -544,21 +542,46 @@ namespace dy.net.job
continue; continue;
} }
// 查询数据库中是否已存在该视频(通过 AwemeId 唯一标识)
var exitVideo = await douyinVideoService.GetByAwemeId(item.AwemeId);
bool Goon = await AutoDistinct(config, exitVideo, cookie); bool Goon = await AutoDistinct(config, exitVideo, cookie);
if (!Goon) if (!Goon)
{ {
continue; continue;
} }
if (exitVideo != null && File.Exists(exitVideo.VideoSavePath)) if (exitVideo != null)
{
//文件存在
if (File.Exists(exitVideo.VideoSavePath))
{
//如果当前时正在下载关注列表的视频,但是已经存在合集下载过了,那么跳过
if (VideoType == VideoTypeEnum.dy_follows && exitVideo.ViedoType == VideoTypeEnum.dy_mix)
{ {
continue; continue;
} }
//如果存在,但是因为去重规则,选择的最高优先级变更了,需要删除原来的,重新下载。 else
if (exitVideo != null) {
//如果当前正在下载合集视频,但是发现已经存在了,但视频类型不是合集,那么删掉原来的记录以及文件,重新下载,合集优先级最高
if (VideoType == VideoTypeEnum.dy_mix && exitVideo.ViedoType != VideoTypeEnum.dy_mix)
{
File.Delete(exitVideo.VideoSavePath);
await douyinVideoService.DeleteById(exitVideo.Id);
}
else
{ {
await douyinVideoService.DeleteById(exitVideo.Id); await douyinVideoService.DeleteById(exitVideo.Id);
} }
}
}
else
{
//文件不存在,直接删掉原始记录
await douyinVideoService.DeleteById(exitVideo.Id);
}
}
var uper = await douyinFollowService.GetByUperId(item.AuthorUserId.ToString(), cookie.MyUserId); var uper = await douyinFollowService.GetByUperId(item.AuthorUserId.ToString(), cookie.MyUserId);
if (uper != null && uper.FullSync) if (uper != null && uper.FullSync)
{ {
@@ -1055,7 +1078,6 @@ namespace dy.net.job
/// </summary> /// </summary>
/// <param name="cookie">用户Cookie</param> /// <param name="cookie">用户Cookie</param>
/// <param name="item">视频信息(包含图片集)</param> /// <param name="item">视频信息(包含图片集)</param>
/// <param name="data">视频信息对象</param>
/// <param name="config">应用配置</param> /// <param name="config">应用配置</param>
/// <param name="followed">应用配置</param> /// <param name="followed">应用配置</param>
/// <param name="cate"></param> /// <param name="cate"></param>
@@ -1432,6 +1454,7 @@ namespace dy.net.job
// 生成NFO文件,动态视频 合成后重新生成,不在这里生成nfo // 生成NFO文件,动态视频 合成后重新生成,不在这里生成nfo
NfoFileGenerator.GenerateVideoNfoFile(video); NfoFileGenerator.GenerateVideoNfoFile(video);
} }
return video; return video;
} }
+1
View File
@@ -38,6 +38,7 @@
public string FollowUserName { get; set; } public string FollowUserName { get; set; }
public string MySelfId { get; set; } public string MySelfId { get; set; }
} }
public class FollowUpdateDto public class FollowUpdateDto
+3
View File
@@ -69,5 +69,8 @@ namespace dy.net.model.entity
/// 标记为非关注的用户-手动增加的 /// 标记为非关注的用户-手动增加的
/// </summary> /// </summary>
public bool IsNoFollowed { get; set; } public bool IsNoFollowed { get; set; }
[SugarColumn(IsNullable = true, Length = 100)]
public string DouyinNo { get; set; }
} }
} }
+19 -19
View File
@@ -1,25 +1,25 @@
//using SqlSugar; using SqlSugar;
//namespace dy.net.model.entity namespace dy.net.model.entity
//{ {
// /// <summary> /// <summary>
// /// ///
// /// </summary> /// </summary>
// [SqlSugar.SugarTable("dy_videoup")] [SqlSugar.SugarTable("dy_videoup")]
// public class DouyinVideoUp public class DouyinVideoUp
// { {
// /// <summary> /// <summary>
// /// ///
// /// </summary> /// </summary>
// [SugarColumn(IsPrimaryKey = true)] [SugarColumn(IsPrimaryKey = true)]
// public string Id { get; set; } public string Id { get; set; }
// [SugarColumn(IsNullable = false, Length = 100)] [SugarColumn(IsNullable = false, Length = 100)]
// public string UperId { get; set; } public string UperId { get; set; }
// public string SavePath { get; set; } public string SavePath { get; set; }
// } }
//} }
+9 -9
View File
@@ -109,11 +109,11 @@ namespace dy.net.model.response
[JsonProperty("sec_uid")] [JsonProperty("sec_uid")]
public string SecUid { get; set; } public string SecUid { get; set; }
///// <summary> /// <summary>
///// ///
///// </summary> /// </summary>
//[JsonProperty("short_id")] [JsonProperty("short_id")]
//public string ShortId { get; set; } public string ShortId { get; set; }
/// <summary> /// <summary>
/// 签名 /// 签名
@@ -1361,10 +1361,10 @@ namespace dy.net.model.response
// ///// // /////
// ///// </summary> // ///// </summary>
// //public string shop_micro_app { get; set; } // //public string shop_micro_app { get; set; }
// ///// <summary> ///// <summary>
// ///// /////
// ///// </summary> ///// </summary>
// //public string short_id { get; set; } //public string short_id { get; set; }
// ///// <summary> // ///// <summary>
// ///// // /////
// ///// </summary> // ///// </summary>
+8 -5
View File
@@ -42,7 +42,7 @@ namespace dy.net.repository
{ {
var where = this.Db.Queryable<DouyinFollowed>() var where = this.Db.Queryable<DouyinFollowed>()
.Where(x => x.mySelfId == dto.MySelfId) .Where(x => x.mySelfId == dto.MySelfId)
.WhereIF(!string.IsNullOrWhiteSpace(dto.FollowUserName), x => x.UperName.Contains(dto.FollowUserName)); .WhereIF(!string.IsNullOrWhiteSpace(dto.FollowUserName), x => x.UperName.Contains(dto.FollowUserName) || x.DouyinNo.Contains(dto.FollowUserName));
var totalCount = await where.CountAsync(); var totalCount = await where.CountAsync();
var list = await where.OrderByDescending(x => x.OpenSync).OrderByDescending(x => x.LastSyncTime).Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync(); var list = await where.OrderByDescending(x => x.OpenSync).OrderByDescending(x => x.LastSyncTime).Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
return (list, totalCount); return (list, totalCount);
@@ -141,8 +141,9 @@ namespace dy.net.repository
bool signatureChanged = !string.Equals(existFollow.Signature, newFollow.Signature, StringComparison.Ordinal); bool signatureChanged = !string.Equals(existFollow.Signature, newFollow.Signature, StringComparison.Ordinal);
bool enterpriseChanged = !string.Equals(existFollow.Enterprise, newFollow.EnterpriseVerifyReason, StringComparison.Ordinal); bool enterpriseChanged = !string.Equals(existFollow.Enterprise, newFollow.EnterpriseVerifyReason, StringComparison.Ordinal);
bool uperAvatarChanged = !string.Equals(existFollow.UperAvatar, newFollow.Avatar?.UrlList?.FirstOrDefault() ?? "", StringComparison.Ordinal); bool uperAvatarChanged = !string.Equals(existFollow.UperAvatar, newFollow.Avatar?.UrlList?.FirstOrDefault() ?? "", StringComparison.Ordinal);
bool dyNoChanged = !string.Equals(existFollow.DouyinNo, newFollow.ShortId ?? "", StringComparison.Ordinal);
if (nameChanged || signatureChanged || uperAvatarChanged || enterpriseChanged) if (nameChanged || signatureChanged || uperAvatarChanged || enterpriseChanged|| dyNoChanged)
{ {
var updateFoll = new DouyinFollowed var updateFoll = new DouyinFollowed
{ {
@@ -153,7 +154,8 @@ namespace dy.net.repository
Signature = newFollow.Signature, Signature = newFollow.Signature,
Enterprise = newFollow.EnterpriseVerifyReason, Enterprise = newFollow.EnterpriseVerifyReason,
UperAvatar = newFollow.Avatar?.UrlList?.FirstOrDefault() ?? "", UperAvatar = newFollow.Avatar?.UrlList?.FirstOrDefault() ?? "",
LastSyncTime = DateTime.UtcNow // 更新同步时间 LastSyncTime = DateTime.UtcNow,// 更新同步时间
DouyinNo = newFollow.ShortId
}; };
if (string.IsNullOrWhiteSpace(existFollow.SavePath)) if (string.IsNullOrWhiteSpace(existFollow.SavePath))
{ {
@@ -178,7 +180,8 @@ namespace dy.net.repository
UperName = follow.NickName, UperName = follow.NickName,
Signature = follow.Signature, Signature = follow.Signature,
UperId = follow.UperId, UperId = follow.UperId,
SavePath= DouyinFileNameHelper.SanitizeLinuxFileName(follow.NickName, follow.UperId, true) SavePath = DouyinFileNameHelper.SanitizeLinuxFileName(follow.NickName, follow.UperId, true),
DouyinNo = follow.ShortId
}; };
bool batchAddSuccess = await BatchProcessAsync(toAddFollows, 200, bool batchAddSuccess = await BatchProcessAsync(toAddFollows, 200,
@@ -198,7 +201,7 @@ namespace dy.net.repository
async batch => async batch =>
{ {
int affectedRows = await Db.Updateable(batch) int affectedRows = await Db.Updateable(batch)
.UpdateColumns(x => new { x.UperName, x.Signature, x.LastSyncTime, x.Enterprise, x.UperAvatar,x.SavePath }) .UpdateColumns(x => new { x.UperName, x.Signature, x.LastSyncTime, x.Enterprise, x.UperAvatar,x.SavePath,x.DouyinNo })
.WhereColumns(x => x.Id) // 按主键匹配 .WhereColumns(x => x.Id) // 按主键匹配
.ExecuteCommandAsync(); .ExecuteCommandAsync();
+38 -33
View File
@@ -34,7 +34,7 @@ namespace dy.net.service
} }
conf.IsFirstRunning = true;//标记为程序刚启动第一次运行 conf.IsFirstRunning = true;//标记为程序刚启动第一次运行
conf.AutoDistinct = true; conf.AutoDistinct = true;
if(!conf.VideoEncoder.HasValue) if (!conf.VideoEncoder.HasValue)
conf.VideoEncoder = 264; conf.VideoEncoder = 264;
sqlSugarClient.Updateable(conf).ExecuteCommand(); sqlSugarClient.Updateable(conf).ExecuteCommand();
//兼容旧版本 //兼容旧版本
@@ -158,37 +158,39 @@ namespace dy.net.service
} }
///// <summary> /// <summary>
///// 获取已经下载过视频的作者的保存路径 /// 获取已经下载过视频的作者的保存路径
///// </summary> /// </summary>
///// <param name="uperId"></param> /// <param name="uperId"></param>
///// <returns></returns> /// <returns></returns>
//public async Task<string> GetDouyinUpSavePath(string uperId) public string GetDouyinUpSavePath(string uperId)
//{ {
// return await sqlSugarClient.Queryable<DouyinVideoUp>().Where(x => x.UperId == uperId).Select(x => x.SavePath).FirstAsync(); return sqlSugarClient.Queryable<DouyinVideoUp>().Where(x => x.UperId == uperId).Select(x => x.SavePath).First();
//} }
///// <summary>
///// 保存下载过视频的作者的保存路径
///// </summary>
///// <param name="uperId"></param>
///// <param name="SavePath"></param>
///// <returns></returns>
//public async Task<bool> SaveDouyinUpSavePath(string uperId, string SavePath)
//{
// var upSavePath = await GetDouyinUpSavePath(uperId); /// <summary>
// if (string.IsNullOrWhiteSpace(upSavePath)) /// 保存下载过视频的作者的保存路径
// { /// </summary>
// await sqlSugarClient.Insertable(new DouyinVideoUp /// <param name="uperId"></param>
// { /// <param name="SavePath"></param>
// Id = IdGener.GetLong().ToString(), /// <returns></returns>
// SavePath = SavePath, public bool SaveDouyinUpSavePath(string uperId, string SavePath)
// UperId = uperId {
// }).ExecuteCommandAsync(); if (string.IsNullOrEmpty(uperId))
// } return false;
// return true; var upSavePath = GetDouyinUpSavePath(uperId);
if (string.IsNullOrWhiteSpace(upSavePath))
{
sqlSugarClient.Insertable(new DouyinVideoUp
{
Id = IdGener.GetLong().ToString(),
SavePath = SavePath,
UperId = uperId
}).ExecuteCommand();
}
return true;
//} }
/// <summary> /// <summary>
/// 将所有关注博主的保存路径统一刷成博主姓名,防止博主名字改变后出现多个文件夹 /// 将所有关注博主的保存路径统一刷成博主姓名,防止博主名字改变后出现多个文件夹
@@ -196,11 +198,11 @@ namespace dy.net.service
/// <returns></returns> /// <returns></returns>
public async Task UpdateFollowedSavePathAsync() public async Task UpdateFollowedSavePathAsync()
{ {
var existNoSavePath =await sqlSugarClient.Queryable<DouyinFollowed>().Where(x => string.IsNullOrWhiteSpace(x.SavePath)).AnyAsync(); var existNoSavePath = await sqlSugarClient.Queryable<DouyinFollowed>().Where(x => string.IsNullOrWhiteSpace(x.SavePath)).AnyAsync();
if (existNoSavePath) if (existNoSavePath)
{ {
var list = await sqlSugarClient.Queryable<DouyinFollowed>().ToListAsync(); var list = await sqlSugarClient.Queryable<DouyinFollowed>().ToListAsync();
var noSavePathList = list.Where(x => string.IsNullOrWhiteSpace(x.SavePath)); var noSavePathList = list.Where(x => string.IsNullOrWhiteSpace(x.SavePath))?.ToList();
foreach (var item in noSavePathList) foreach (var item in noSavePathList)
{ {
var path = DouyinFileNameHelper.SanitizeLinuxFileName(item.UperName, "抖音号" + item.UperId, true); var path = DouyinFileNameHelper.SanitizeLinuxFileName(item.UperName, "抖音号" + item.UperId, true);
@@ -215,7 +217,10 @@ namespace dy.net.service
item.SavePath = path; item.SavePath = path;
} }
} }
await sqlSugarClient.Updateable(list).UpdateColumns(x => new { x.SavePath }).ExecuteCommandAsync(); if (noSavePathList != null)
{
await sqlSugarClient.Updateable(noSavePathList).UpdateColumns(x => new { x.SavePath }).ExecuteCommandAsync();
}
} }
} }
#region #region
+2 -2
View File
@@ -203,8 +203,8 @@ namespace dy.net.service
IsCollectEnabled = cookies.Any(x => x.DownCollect && !x.UseCollectFolder && !string.IsNullOrWhiteSpace(x.SavePath)), IsCollectEnabled = cookies.Any(x => x.DownCollect && !x.UseCollectFolder && !string.IsNullOrWhiteSpace(x.SavePath)),
IsFavoriteEnabled = cookies.Any(x => x.DownFavorite && !string.IsNullOrWhiteSpace(x.FavSavePath)), IsFavoriteEnabled = cookies.Any(x => x.DownFavorite && !string.IsNullOrWhiteSpace(x.FavSavePath)),
IsFollowedEnabled = cookies.Any(x => x.DownFollowd && !string.IsNullOrWhiteSpace(x.UpSavePath)), IsFollowedEnabled = cookies.Any(x => x.DownFollowd && !string.IsNullOrWhiteSpace(x.UpSavePath)),
IsMixEnabled = cookies.Any(x => x.DownMix && !string.IsNullOrWhiteSpace(x.MixPath) && !string.IsNullOrWhiteSpace(x.SavePath)), IsMixEnabled = cookies.Any(x => x.DownMix && !string.IsNullOrWhiteSpace(x.MixPath)),
IsSeriesEnabled = cookies.Any(x => x.DownSeries && !string.IsNullOrWhiteSpace(x.SeriesPath) && !string.IsNullOrWhiteSpace(x.SavePath)), IsSeriesEnabled = cookies.Any(x => x.DownSeries && !string.IsNullOrWhiteSpace(x.SeriesPath)),
IsCustomCollectEnabled = cookies.Any(x => x.UseCollectFolder && !string.IsNullOrWhiteSpace(x.SavePath)) IsCustomCollectEnabled = cookies.Any(x => x.UseCollectFolder && !string.IsNullOrWhiteSpace(x.SavePath))
}; };
} }