界面优化

This commit is contained in:
lijianyou
2025-10-22 22:22:49 +08:00
parent 1b989df796
commit 4db590cfb9
13 changed files with 261 additions and 76 deletions
+24
View File
@@ -1,6 +1,9 @@
using dy.net.dto;
using dy.net.service;
using dy.net.utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Drawing.Printing;
namespace dy.net.Controllers
@@ -50,7 +53,28 @@ namespace dy.net.Controllers
data
});
}
[AllowAnonymous]
[HttpGet]
public IActionResult Index()
{
List<MyClass> myClasses = new List<MyClass>();
foreach (var drive in DriveInfo.GetDrives())
{
myClasses.Add(new MyClass { name=drive.Name, x1= drive.TotalSize, x2= drive.TotalFreeSpace });
Serilog.Log.Debug($"Drive: {drive.Name}, Total Size: {drive.TotalSize}, Free Space: {drive.TotalFreeSpace}");
}
//var disk=DiskInfoHelper.GetDockerHostTotalDiskSpaceGB();
return Ok(JsonConvert.SerializeObject(myClasses)+"\r\n"+JsonConvert.SerializeObject(myClasses.Sum(x=>x.x1)+"\r\n"+ JsonConvert.SerializeObject(myClasses.Sum(x => x.x2))));
}
public class MyClass
{
public string name { get; set; }
public long x1 { get; set; }
public long x2 { get; set; }
}
}
}
+2 -1
View File
@@ -182,7 +182,8 @@ namespace dy.net
var quartzJobService = services.GetRequiredService<QuartzJobService>();
quartzJobService.StartJob(config?.Cron ?? "30");
Serilog.Log.Debug("系统初始化完成,会默认将-博主作品同步功能-同步全部作品重置为关闭(若要开启,可以到抖音授权菜单中更改)");
Serilog.Log.Debug("系统初始化完成,会默认将-博主作品同步功能-同步全部作品重置为关闭(若要开启,可以到抖音授权页面中修改)");
Serilog.Log.Debug($"默认设置的每次读取行数为:{config.BatchCount},可前往系统配置页修改");
}
catch (Exception ex)
{
@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project>
<PropertyGroup>
<_PublishTargetUrl>F:\work\code\me\dysync.net\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2025-10-22T07:01:04.1668366Z||;True|2025-10-22T14:49:43.6340569+08:00||;True|2025-10-22T14:38:39.4685603+08:00||;True|2025-10-21T18:35:28.8392541+08:00||;True|2025-10-20T10:31:05.5865212+08:00||;True|2025-10-20T10:20:41.5717101+08:00||;True|2025-10-19T10:08:33.6669332+08:00||;False|2025-10-19T10:07:22.3337545+08:00||;False|2025-10-19T10:05:22.9484805+08:00||;True|2025-10-10T16:54:27.1472888+08:00||;False|2025-10-10T16:53:44.1700030+08:00||;False|2025-10-10T16:52:48.1740453+08:00||;False|2025-10-10T16:51:21.5067253+08:00||;False|2025-10-10T16:50:19.2140597+08:00||;False|2025-10-10T16:49:21.2213290+08:00||;False|2025-10-10T16:48:47.7229948+08:00||;False|2025-10-10T16:48:15.1258700+08:00||;True|2025-09-30T13:29:42.2354235+08:00||;True|2025-09-25T11:44:52.6858389+08:00||;True|2025-09-25T11:08:27.8810109+08:00||;True|2025-09-25T09:28:50.2563374+08:00||;True|2025-09-24T16:14:02.3072184+08:00||;True|2025-09-23T22:38:52.4414757+08:00||;True|2025-09-23T22:19:07.1006356+08:00||;True|2025-09-23T22:18:01.5945225+08:00||;True|2025-09-23T22:06:15.6293613+08:00||;True|2025-09-23T21:53:14.2977444+08:00||;True|2025-09-23T21:46:55.2322411+08:00||;False|2025-09-23T21:45:23.7858854+08:00||;False|2025-09-23T21:03:51.8325689+08:00||;True|2025-09-23T10:03:32.2251920+08:00||;False|2025-09-23T09:38:08.2372201+08:00||;False|2025-09-23T09:37:49.9390545+08:00||;True|2024-03-11T21:31:45.8102398+08:00||;True|2024-03-11T07:26:24.7660541+08:00||;True|2024-03-08T22:08:40.0154831+08:00||;True|2024-03-03T10:14:36.8109114+08:00||;True|2024-03-02T18:44:57.3288537+08:00||;True|2024-01-24T17:51:37.9164415+08:00||;True|2024-01-24T16:36:50.5612157+08:00||;True|2024-01-24T15:51:35.7556653+08:00||;True|2024-01-17T23:40:40.7526618+08:00||;True|2024-01-17T23:36:10.3692844+08:00||;True|2024-01-17T23:22:03.2378834+08:00||;True|2024-01-03T11:35:44.7118292+08:00||;True|2024-01-03T11:11:23.4270453+08:00||;True|2024-01-03T11:04:35.2081526+08:00||;True|2024-01-03T10:57:03.7053107+08:00||;True|2024-01-03T10:51:50.7463989+08:00||;False|2024-01-03T10:50:24.9775312+08:00||;True|2024-01-03T10:47:30.1128183+08:00||;True|2024-01-03T10:42:55.8640657+08:00||;True|2024-01-03T09:24:24.3436056+08:00||;True|2024-01-02T23:40:38.2001198+08:00||;True|2024-01-02T23:08:36.7230444+08:00||;True|2024-01-02T22:53:43.9658255+08:00||;True|2024-01-02T22:25:38.5545279+08:00||;False|2024-01-02T22:24:42.6577609+08:00||;True|2024-01-02T22:04:33.4708889+08:00||;True|2024-01-02T21:49:57.9249898+08:00||;True|2023-12-28T22:42:58.5976180+08:00||;True|2023-12-28T22:24:09.2051205+08:00||;True|2023-12-28T22:05:48.4865497+08:00||;True|2023-12-28T21:50:57.4549336+08:00||;True|2023-12-28T21:45:30.4557939+08:00||;True|2023-12-28T21:19:59.3614594+08:00||;False|2023-12-28T21:17:04.3069097+08:00||;False|2023-12-28T21:15:56.7788810+08:00||;False|2023-12-28T21:14:57.3617402+08:00||;False|2023-12-28T21:10:45.4382469+08:00||;True|2023-12-28T19:45:33.1431914+08:00||;True|2023-12-26T11:30:36.6418716+08:00||;True|2023-12-26T11:17:40.6433651+08:00||;True|2023-12-26T09:13:56.0741559+08:00||;True|2023-12-26T09:10:55.5358737+08:00||;True|2023-12-25T23:15:34.6534359+08:00||;True|2023-12-25T23:09:47.1566176+08:00||;False|2023-12-25T23:07:32.1118803+08:00||;True|2023-12-25T22:59:50.4643459+08:00||;True|2023-12-25T22:50:14.3584798+08:00||;False|2023-12-25T22:49:20.0279513+08:00||;True|2023-12-25T22:44:07.4183973+08:00||;True|2023-12-25T22:35:27.3847085+08:00||;True|2023-12-25T22:23:21.3542658+08:00||;True|2023-12-25T22:12:00.5219522+08:00||;True|2023-12-25T16:52:12.5089621+08:00||;True|2023-12-25T16:43:30.8348193+08:00||;True|2023-12-25T16:35:08.2421925+08:00||;True|2023-12-25T16:25:21.3233455+08:00||;False|2023-12-25T16:24:39.1703901+08:00||;True|2023-12-25T16:24:01.4340091+08:00||;True|2023-12-25T16:10:06.5213850+08:00||;True|2023-12-25T15:42:17.1376331+08:00||;True|2023-12-25T15:29:47.8537015+08:00||;True|2023-12-25T14:04:54.3750643+08:00||;False|2023-12-25T14:04:07.9330700+08:00||;True|2023-12-25T13:51:58.1949269+08:00||;True|2023-12-25T13:41:42.4832670+08:00||;True|2023-12-25T13:00:25.3861450+08:00||;True|2023-12-25T12:48:45.3851245+08:00||;</History>
<History>True|2025-10-22T14:08:11.6423148Z||;True|2025-10-22T21:54:24.7180547+08:00||;True|2025-10-22T21:40:03.5194315+08:00||;True|2025-10-22T21:28:28.8962766+08:00||;True|2025-10-22T21:22:47.9631689+08:00||;True|2025-10-22T21:18:24.5274318+08:00||;True|2025-10-22T21:14:51.6386326+08:00||;False|2025-10-22T21:14:07.6282769+08:00||;True|2025-10-22T21:03:48.9892860+08:00||;True|2025-10-22T21:00:56.3617243+08:00||;False|2025-10-22T21:00:30.5472941+08:00||;True|2025-10-22T20:51:29.6155916+08:00||;False|2025-10-22T20:50:47.1882956+08:00||;True|2025-10-22T15:01:04.1668366+08:00||;True|2025-10-22T14:49:43.6340569+08:00||;True|2025-10-22T14:38:39.4685603+08:00||;True|2025-10-21T18:35:28.8392541+08:00||;True|2025-10-20T10:31:05.5865212+08:00||;True|2025-10-20T10:20:41.5717101+08:00||;True|2025-10-19T10:08:33.6669332+08:00||;False|2025-10-19T10:07:22.3337545+08:00||;False|2025-10-19T10:05:22.9484805+08:00||;True|2025-10-10T16:54:27.1472888+08:00||;False|2025-10-10T16:53:44.1700030+08:00||;False|2025-10-10T16:52:48.1740453+08:00||;False|2025-10-10T16:51:21.5067253+08:00||;False|2025-10-10T16:50:19.2140597+08:00||;False|2025-10-10T16:49:21.2213290+08:00||;False|2025-10-10T16:48:47.7229948+08:00||;False|2025-10-10T16:48:15.1258700+08:00||;True|2025-09-30T13:29:42.2354235+08:00||;True|2025-09-25T11:44:52.6858389+08:00||;True|2025-09-25T11:08:27.8810109+08:00||;True|2025-09-25T09:28:50.2563374+08:00||;True|2025-09-24T16:14:02.3072184+08:00||;True|2025-09-23T22:38:52.4414757+08:00||;True|2025-09-23T22:19:07.1006356+08:00||;True|2025-09-23T22:18:01.5945225+08:00||;True|2025-09-23T22:06:15.6293613+08:00||;True|2025-09-23T21:53:14.2977444+08:00||;True|2025-09-23T21:46:55.2322411+08:00||;False|2025-09-23T21:45:23.7858854+08:00||;False|2025-09-23T21:03:51.8325689+08:00||;True|2025-09-23T10:03:32.2251920+08:00||;False|2025-09-23T09:38:08.2372201+08:00||;False|2025-09-23T09:37:49.9390545+08:00||;True|2024-03-11T21:31:45.8102398+08:00||;True|2024-03-11T07:26:24.7660541+08:00||;True|2024-03-08T22:08:40.0154831+08:00||;True|2024-03-03T10:14:36.8109114+08:00||;True|2024-03-02T18:44:57.3288537+08:00||;True|2024-01-24T17:51:37.9164415+08:00||;True|2024-01-24T16:36:50.5612157+08:00||;True|2024-01-24T15:51:35.7556653+08:00||;True|2024-01-17T23:40:40.7526618+08:00||;True|2024-01-17T23:36:10.3692844+08:00||;True|2024-01-17T23:22:03.2378834+08:00||;True|2024-01-03T11:35:44.7118292+08:00||;True|2024-01-03T11:11:23.4270453+08:00||;True|2024-01-03T11:04:35.2081526+08:00||;True|2024-01-03T10:57:03.7053107+08:00||;True|2024-01-03T10:51:50.7463989+08:00||;False|2024-01-03T10:50:24.9775312+08:00||;True|2024-01-03T10:47:30.1128183+08:00||;True|2024-01-03T10:42:55.8640657+08:00||;True|2024-01-03T09:24:24.3436056+08:00||;True|2024-01-02T23:40:38.2001198+08:00||;True|2024-01-02T23:08:36.7230444+08:00||;True|2024-01-02T22:53:43.9658255+08:00||;True|2024-01-02T22:25:38.5545279+08:00||;False|2024-01-02T22:24:42.6577609+08:00||;True|2024-01-02T22:04:33.4708889+08:00||;True|2024-01-02T21:49:57.9249898+08:00||;True|2023-12-28T22:42:58.5976180+08:00||;True|2023-12-28T22:24:09.2051205+08:00||;True|2023-12-28T22:05:48.4865497+08:00||;True|2023-12-28T21:50:57.4549336+08:00||;True|2023-12-28T21:45:30.4557939+08:00||;True|2023-12-28T21:19:59.3614594+08:00||;False|2023-12-28T21:17:04.3069097+08:00||;False|2023-12-28T21:15:56.7788810+08:00||;False|2023-12-28T21:14:57.3617402+08:00||;False|2023-12-28T21:10:45.4382469+08:00||;True|2023-12-28T19:45:33.1431914+08:00||;True|2023-12-26T11:30:36.6418716+08:00||;True|2023-12-26T11:17:40.6433651+08:00||;True|2023-12-26T09:13:56.0741559+08:00||;True|2023-12-26T09:10:55.5358737+08:00||;True|2023-12-25T23:15:34.6534359+08:00||;True|2023-12-25T23:09:47.1566176+08:00||;False|2023-12-25T23:07:32.1118803+08:00||;True|2023-12-25T22:59:50.4643459+08:00||;True|2023-12-25T22:50:14.3584798+08:00||;False|2023-12-25T22:49:20.0279513+08:00||;True|2023-12-25T22:44:07.4183973+08:00||;True|2023-12-25T22:35:27.3847085+08:00||;True|2023-12-25T22:23:21.3542658+08:00||;True|2023-12-25T22:12:00.5219522+08:00||;True|2023-12-25T16:52:12.5089621+08:00||;True|2023-12-25T16:43:30.8348193+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>
+1 -1
View File
@@ -28,7 +28,7 @@ onMounted(() => {
<template>
<ThemeProvider :color="{ middle: { 'bg-base': '#fff','bg-container':'#fff','bg-container-light':'#fff' }, primary: { DEFAULT: '#1896ff' } }" :autoAdapt="true">
<div class="front-view flex flex-col" style="background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)">
<div class="text-xxl text-text hover:text-text" style="margin-left:20px;">
<div class="text-xxl text-text hover:text-text" style="margin-left:20px;color:#722ed1;">
<img src="/logo1.png" />
dy.sync.net
</div>
+18 -15
View File
@@ -1,30 +1,32 @@
<template>
<ThemeProvider :color="{ middle: { 'bg-base': '#1a1a1a' }, primary: { DEFAULT: '#36bffA' } }">
<!-- 加宽后的登录框使用更大的宽度设置 -->
<div class="login-box rounded-lg bg-gray-900 shadow-lg p-8 max-w-2xl mx-auto my-10 border border-gray-800 transition-all duration-300 hover:shadow-xl">
<a-form :model="form" :wrapperCol="{ span: 24 }" @finish="login" class="login-form w-full p-lg text-gray-200">
<ThemeProvider :color="{
middle: { 'bg-base': '#f8fafc' }, // 浅灰底色
primary: { DEFAULT: '#60a5fa' } // 柔和蓝色作为主色调
}">
<!-- 清新风格登录框 -->
<div class="login-box rounded-xl bg-white shadow-md p-8 max-w-2xl mx-auto my-10 border border-gray-100 transition-all duration-300 hover:shadow-lg">
<a-form :model="form" :wrapperCol="{ span: 24 }" @finish="login" class="login-form w-full p-lg text-gray-700">
<div class="third-platform">
<div class="third-title mb-6 text-xl text-center font-semibold text-white">抖音同步小帮手</div>
<div class="third-title mb-6 text-xl text-center font-semibold text-gray-800">抖音同步小帮手</div>
</div>
<a-divider class="my-6 bg-gray-700"></a-divider>
<a-divider class="my-6 bg-gray-200"></a-divider>
<!-- 增加输入框宽度并调整间距 -->
<!-- 清新风格输入框 -->
<a-form-item :required="true" name="username" class="mb-5">
<a-input v-model:value="form.username" autocomplete="new-username" placeholder="请输入用户名" class="login-input h-[45px] rounded-md bg-gray-800 border-gray-700 text-white placeholder:text-gray-500 focus:border-primary text-lg" />
<a-input v-model:value="form.username" autocomplete="new-username" placeholder="请输入用户名" class="login-input h-[45px] rounded-md bg-gray-50 border-gray-200 text-gray-800 placeholder:text-gray-400 focus:border-primary text-base transition-all focus:ring-1 focus:ring-primary" />
</a-form-item>
<a-form-item :required="true" name="password" class="mb-6">
<a-input v-model:value="form.password" autocomplete="new-password" placeholder="请输入密码" class="login-input h-[45px] rounded-md text-white placeholder:text-gray-500 focus:border-primary text-lg" :type="showPassword ? 'text' : 'password'">
<!-- 密码显示/隐藏切换按钮 -->
<!-- 直接使用图标作为点击元素 -->
<a-input v-model:value="form.password" autocomplete="new-password" placeholder="请输入密码" class="login-input h-[45px] rounded-md bg-gray-50 border-gray-200 text-gray-800 placeholder:text-gray-400 focus:border-primary text-base transition-all focus:ring-1 focus:ring-primary" :type="showPassword ? 'text' : 'password'">
<!-- 密码显示/隐藏图标 -->
<template #suffix>
<EyeOutlined v-if="showPassword" @click="showPassword = !showPassword" class="text-gray-500 hover:text-white cursor-pointer transition-colors" aria-label="隐藏密码" />
<EyeInvisibleOutlined v-else @click="showPassword = !showPassword" class="text-gray-500 hover:text-white cursor-pointer transition-colors" aria-label="显示密码" />
<EyeOutlined v-if="showPassword" @click="showPassword = !showPassword" class="text-gray-400 hover:text-primary cursor-pointer transition-colors" aria-label="隐藏密码" />
<EyeInvisibleOutlined v-else @click="showPassword = !showPassword" class="text-gray-400 hover:text-primary cursor-pointer transition-colors" aria-label="显示密码" />
</template>
</a-input>
</a-form-item>
<a-button htmlType="submit" class="h-[48px] w-full rounded-md transition-colors hover:opacity-90 bg-primary border-primary text-lg" type="primary" :loading="loading">
<a-button htmlType="submit" class="h-[48px] w-full rounded-md transition-colors hover:bg-primary/90 bg-primary border-primary text-white text-base shadow-sm hover:shadow" type="primary" :loading="loading">
登录
</a-button>
</a-form>
@@ -36,6 +38,7 @@
import { reactive, ref } from 'vue';
import { useAccountStore } from '@/store';
import { ThemeProvider } from 'stepin';
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue';
// 控制密码显示/隐藏的状态
const showPassword = ref(false);
@@ -68,4 +71,4 @@ function login(params: LoginFormProps) {
})
.finally(() => (loading.value = false));
}
</script>
</script>
+30 -37
View File
@@ -1,50 +1,43 @@
<template>
<a-modal
width="460px"
v-model:visible="_visible"
wrap-class-name="login-modal"
:closable="false"
:footer="null"
:body-style="{ padding: 0 }"
>
<a-modal width="460px" v-model:visible="_visible" wrap-class-name="login-modal" :closable="false" :footer="null" :body-style="{ padding: 0 }">
<login-box />
</a-modal>
</template>
<script lang="ts" setup>
import LoginBox from './LoginBox.vue';
import useModelValue from '@/utils/useModelValue';
import { useAccountStore } from '@/store';
import { useRoute } from 'vue-router';
import { computed } from 'vue';
import LoginBox from './LoginBox.vue';
import useModelValue from '@/utils/useModelValue';
import { useAccountStore } from '@/store';
import { useRoute } from 'vue-router';
import { computed } from 'vue';
const props = defineProps({
visible: { type: Boolean, default: undefined },
unless: Array<String>,
});
const props = defineProps({
visible: { type: Boolean, default: undefined },
unless: Array<String>,
});
const accountStore = useAccountStore();
const route = useRoute();
const accountStore = useAccountStore();
const route = useRoute();
const emit = defineEmits<{
(e: 'update:visible', visible?: boolean): void;
}>();
const emit = defineEmits<{
(e: 'update:visible', visible?: boolean): void;
}>();
const _visible = computed({
get(): boolean {
return !!sVisible.value && !props.unless?.includes(route.fullPath);
},
set(val: boolean) {
sVisible.value = val;
},
});
const _visible = computed({
get(): boolean {
return !!sVisible.value && !props.unless?.includes(route.fullPath);
},
set(val: boolean) {
sVisible.value = val;
},
});
const { value: sVisible } = useModelValue(
() => props.visible ?? !accountStore.logged,
(val) => emit('update:visible', val)
);
const { value: sVisible } = useModelValue(
() => props.visible ?? !accountStore.logged,
(val) => emit('update:visible', val)
);
</script>
<style lang="less">
.login-modal .ant-modal-content {
@apply bg-transparent;
}
.login-modal .ant-modal-content {
@apply bg-transparent;
}
</style>
+1 -1
View File
@@ -28,7 +28,7 @@
</svg>
</div>
</div>
<div class="stat-value">{{ fileSizeTotal }} G / {{totalDiskSize}} G</div>
<div class="stat-value">{{ fileSizeTotal }} G</div>
<div class="stat-trend"></div>
</div>
</section>
+3 -3
View File
@@ -87,7 +87,7 @@ const routes: RouteRecordRaw[] = [
path: '/dashboard',
name: '数据看板',
meta: {
icon: 'SettingOutlined',
icon: 'RadarChartOutlined',
view: 'self',
target: '_self',
renderMenu: true,
@@ -99,7 +99,7 @@ const routes: RouteRecordRaw[] = [
path: '/workplace',
name: '同步记录',
meta: {
icon: 'SettingOutlined',
icon: 'SwapOutlined',
view: 'self',
target: '_self',
renderMenu: true,
@@ -111,7 +111,7 @@ const routes: RouteRecordRaw[] = [
path: '/cok',
name: '抖音授权',
meta: {
icon: 'SettingOutlined',
icon: 'SafetyCertificateOutlined',
view: 'self',
target: '_self',
renderMenu: true,
+8 -7
View File
@@ -39,9 +39,10 @@ namespace dy.net.job
{
count = config.BatchCount.ToString();
}
Serilog.Log.Debug($"collect-当前设置的每次扫描行数为:{count}");
var cookies = await _dyCookieService.GetAllCookies();
cookies= cookies.Where(c => !string.IsNullOrWhiteSpace(c.SavePath)).ToList();
if (cookies == null || !cookies.Any())
{
Serilog.Log.Debug("collect-无可用Cookie,任务终止");
@@ -49,7 +50,7 @@ namespace dy.net.job
}
else
{
Serilog.Log.Debug($"collect-当前有{cookies.Count}个cookie开启了同步,即将开始同步");
//Serilog.Log.Debug($"collect-当前有{cookies.Count}个cookie开启了同步,即将开始同步");
//return;
}
@@ -65,11 +66,11 @@ namespace dy.net.job
Serilog.Log.Debug($"collect-Cookie-[{cookie.UserName}]无效,跳过");
continue;
}
if (string.IsNullOrWhiteSpace(cookie.SavePath))
{
Serilog.Log.Debug($"collect-Cookie-[{cookie.UserName}]未设置保存路径,跳过");
continue;
}
//if (string.IsNullOrWhiteSpace(cookie.SavePath))
//{
// Serilog.Log.Debug($"collect-Cookie-[{cookie.UserName}]未设置保存路径,跳过");
// continue;
//}
try
{
int syncCount = 0;// 记录本次Cookie同步的视频数量
+1
View File
@@ -41,6 +41,7 @@ namespace dy.net.job
count = config.BatchCount.ToString();
}
var cookies = await _dyCookieService.GetAllCookies();
cookies=cookies.Where(c => !string.IsNullOrWhiteSpace(c.FavSavePath)).ToList();
if (cookies == null || !cookies.Any())
{
Serilog.Log.Debug("favorite-无可用Cookie,任务终止");
+8 -9
View File
@@ -42,28 +42,27 @@ namespace dy.net.job
{
count = config.BatchCount.ToString();
}
Serilog.Log.Debug($"dyuploder-当前设置的每次扫描行数为:{count}");
var cookies = await _dyCookieService.GetAllCookies();
cookies = cookies.Where(x => !string.IsNullOrWhiteSpace(x.UpSecUserIds))?.ToList();
cookies = cookies.Where(x => !string.IsNullOrWhiteSpace(x.UpSecUserIds)&&!string.IsNullOrWhiteSpace(x.UpSavePath))?.ToList();
if (!cookies.Any())
{
Serilog.Log.Debug("dyuploder-无可用抖音UP主SecUserId,任务终止");
Serilog.Log.Debug("dyuploder-无可用cookie,任务终止");
return;
}
else
{
Serilog.Log.Debug($"dyuploder-当前有{cookies.Count}个cookie开启了同步,即将开始同步");
//Serilog.Log.Debug($"dyuploder-当前有{cookies.Count}个cookie开启了同步,即将开始同步");
//return;
}
foreach (var cookie in cookies)
{
if(string.IsNullOrWhiteSpace(cookie.UpSavePath))
{
Serilog.Log.Debug($"dyuploder-Cookie[{cookie.UserName}]的UP主保存路径无效,跳过");
continue;
}
//if(string.IsNullOrWhiteSpace(cookie.UpSavePath))
//{
// Serilog.Log.Debug($"dyuploder-Cookie[{cookie.UserName}]的UP主保存路径无效,跳过");
// continue;
//}
var ups=JsonConvert.DeserializeObject<List<DyUpSecUserIdDto>>(cookie.UpSecUserIds);
foreach (var uper in ups)
+1 -1
View File
@@ -76,7 +76,7 @@ namespace dy.net.service
VideoCollectSize = ByteToGbConverter.ConvertBytesToGb(list.Where(x => x.ViedoType == "2").Sum(x => x.FileSize)),
VideoFollowSize = ByteToGbConverter.ConvertBytesToGb(list.Where(x => x.ViedoType == "3").Sum(x => x.FileSize)),
TotalDiskSize= ByteToGbConverter.GetHostTotalDiskSpaceGB(),
//TotalDiskSize= ByteToGbConverter.GetHostTotalDiskSpaceGB(),
};
data.Authors = list.GroupBy(x => x.Author).Select(x => new VideoStaticsItemDto { Name = x.Key, Count = x.LongCount(), Icon = x.FirstOrDefault().AuthorAvatarUrl }).OrderByDescending(d => d.Count).ToList();
return data;
+163
View File
@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace dy.net.utils
{
public static class DiskInfoHelper
{/// <summary>
/// 在Docker容器中获取Linux宿主机的本地固定磁盘总空间(GB)
/// 前提:宿主机需挂载 /proc 到容器内的 /host/proc(启动时加 -v /proc:/host/proc:ro
/// </summary>
/// <returns>总空间字符串(如 "1408.35 GB"),失败时返回错误信息</returns>
public static string GetDockerHostTotalDiskSpaceGB()
{
try
{
// 1. 检查是否为Linux宿主机(Docker主要运行在Linux上)
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return "仅支持Linux宿主机(Docker容器内)";
}
// 2. 检查宿主机/proc是否已挂载到容器
string hostProcMountsPath = "/app/db/mounts";
if (!File.Exists(hostProcMountsPath))
{
return "未检测到宿主机/proc挂载,请使用 -v /proc:/host/proc:ro 启动容器";
}
// 3. 从宿主机/proc/mounts筛选物理磁盘挂载点(排除虚拟文件系统)
var physicalMounts = GetHostPhysicalMounts(hostProcMountsPath);
if (!physicalMounts.Any())
{
return "未找到宿主机的物理磁盘挂载点";
}
// 4. 计算所有物理磁盘的总空间(通过df命令获取挂载点的总空间)
long totalBytes = 0;
foreach (var mountPoint in physicalMounts)
{
// 执行df命令获取宿主机挂载点的总空间(需容器内有df工具,或通过/proc/diskstats计算)
var (success, bytes) = GetMountPointTotalBytes(mountPoint);
if (success)
{
totalBytes += bytes;
}
}
if (totalBytes == 0)
{
return "无法读取宿主机磁盘空间(可能权限不足)";
}
// 5. 转换为GB
return ConvertBytesToGb(totalBytes);
}
catch (Exception ex)
{
return $"获取宿主机磁盘空间失败:{ex.Message}";
}
}
/// <summary>
/// 从宿主机/proc/mounts筛选物理磁盘挂载点(排除虚拟文件系统)
/// </summary>
private static List<string> GetHostPhysicalMounts(string hostProcMountsPath)
{
var physicalMounts = new List<string>();
// 虚拟文件系统类型(排除这些类型,剩下的视为物理磁盘相关)
var virtualFsTypes = new HashSet<string>
{
"tmpfs", "sysfs", "proc", "devtmpfs", "devpts", "cgroup", "cgroup2",
"securityfs", "pstore", "debugfs", "hugetlbfs", "mqueue", "configfs",
"fusectl", "overlay", "squashfs", "overlay2" // overlay/overlay2是Docker自身的存储驱动,需排除
};
foreach (var line in File.ReadAllLines(hostProcMountsPath))
{
var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length >= 3)
{
string device = parts[0]; // 设备名(如/dev/sda1
string mountPoint = parts[1]; // 挂载点(如/
string fsType = parts[2]; // 文件系统类型
// 筛选条件:非虚拟文件系统 + 设备名以/dev/开头(物理设备)
if (!virtualFsTypes.Contains(fsType) && device.StartsWith("/dev/"))
{
physicalMounts.Add(mountPoint);
}
}
}
return physicalMounts.Distinct().ToList();
}
/// <summary>
/// 通过df命令获取宿主机挂载点的总空间(字节)
/// (需容器内安装coreutils,或替换为解析/proc/diskstats的逻辑)
/// </summary>
private static (bool success, long totalBytes) GetMountPointTotalBytes(string hostMountPoint)
{
try
{
// 在容器内执行df命令,指定宿主机的挂载点(需宿主机路径在容器内可见,或通过/proc计算)
// 注意:df命令返回的是1K-blocks,需转换为字节(*1024
var process = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "df",
Arguments = $"-P {hostMountPoint}", // -P 确保输出格式一致
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
if (process.ExitCode != 0)
{
return (false, 0);
}
// 解析df输出(第二行为数据行)
var lines = output.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
if (lines.Length < 2)
{
return (false, 0);
}
var dataParts = lines[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (dataParts.Length >= 2 && long.TryParse(dataParts[1], out long blocks))
{
return (true, blocks * 1024); // 1K-blocks -> 字节
}
return (false, 0);
}
catch
{
return (false, 0);
}
}
/// <summary>
/// 字节转GB1GB = 1024^3字节)
/// </summary>
private static string ConvertBytesToGb(long bytes)
{
if (bytes <= 0) return "磁盘空间计算错误";
double gb = (double)bytes / (1024 * 1024 * 1024);
return $"{gb:F2} GB";
}
}
}