diff --git a/Appsettings.cs b/Appsettings.cs index c61c438..3333ef1 100644 --- a/Appsettings.cs +++ b/Appsettings.cs @@ -1,8 +1,4 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Configuration.Json; -using System; -using System.Collections.Generic; -using System.Linq; +using Microsoft.Extensions.Configuration.Json; namespace dy.net { diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs index 531712f..c54a07d 100644 --- a/Controllers/AuthController.cs +++ b/Controllers/AuthController.cs @@ -1,13 +1,13 @@ using ClockSnowFlake; +using dy.net.model.dto; +using dy.net.service; +using dy.net.utils; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; -using dy.net.service; -using dy.net.utils; -using dy.net.model.dto; namespace dy.net.Controllers { @@ -50,7 +50,7 @@ namespace dy.net.Controllers return ApiResult.Success(new { user?.Avatar, user?.Id, user?.UserName }); } - + /// diff --git a/Controllers/CateController.cs b/Controllers/CateController.cs index b11e8a3..56dddd0 100644 --- a/Controllers/CateController.cs +++ b/Controllers/CateController.cs @@ -1,9 +1,7 @@ using dy.net.model.dto; -using dy.net.model.entity; using dy.net.service; using dy.net.utils; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace dy.net.Controllers @@ -56,12 +54,12 @@ namespace dy.net.Controllers public async Task BatchSave(List dto) { - if(dto.Any(x=> !DouyinFileNameHelper.IsValidWithoutSpecialChars(x.SaveFolder))) + if (dto.Any(x => !DouyinFileNameHelper.IsValidWithoutSpecialChars(x.SaveFolder))) { return ApiResult.Fail("有部分文件名不符合要求,请检查"); } - var result= await _douyinCollectCateService.BatchSwitchSync(dto); + var result = await _douyinCollectCateService.BatchSwitchSync(dto); return ApiResult.SuccOrFail(result, result); } diff --git a/Controllers/ConfigController.cs b/Controllers/ConfigController.cs index 0165f1c..f35cfd9 100644 --- a/Controllers/ConfigController.cs +++ b/Controllers/ConfigController.cs @@ -6,14 +6,8 @@ using dy.net.service; using dy.net.utils; using dy.sync.lib; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; -using Quartz.Util; -using System.Text; -using System.Text.Json; -using System.Xml.Linq; -using static Dm.net.buffer.ByteArrayBuffer; namespace dy.net.Controllers { @@ -64,50 +58,53 @@ namespace dy.net.Controllers } - /// - /// 导入配置 - /// - /// - /// [HttpPost("importConf")] public async Task ImportConf(AppConfigImportDto dto) { if (dto == null) return ApiResult.Fail("json数据为空"); - var follows = dto.follows; - if (follows != null && follows.Count > 0) - { - var add = await douyinFollowService.AddHandFollows(follows); - if (add) - Serilog.Log.Debug("关注列表导入成功"); - } - - var conf = dto.conf; - if (conf != null) - { - if (conf.BatchCount > 30) - { - Serilog.Log.Debug("$对不起,为了项目能长久稳定运行,还是最大不要超过30吧。。。"); - conf.BatchCount = 30; - } - var update = await commonService.UpdateConfig(conf); - if (update) - Serilog.Log.Debug("系统配置导入成功"); - } - var cookies = dto.cookies; - - if (cookies != null && cookies.Count > 0) - { - var importCookies = await douyinCookieService.ImportCookies(cookies); - if (importCookies) - { - Serilog.Log.Debug("抖音Cookie配置导入成功"); - } - } + await HandleFollowsImport(dto.follows); + await HandleConfigImport(dto.conf); + await HandleCookiesImport(dto.cookies); return ApiResult.Success(); } + + private async Task HandleFollowsImport(List follows) + { + if (follows?.Count > 0) + { + var added = await douyinFollowService.AddHandFollows(follows); + if (added) + Serilog.Log.Debug("关注列表导入成功"); + } + } + + private async Task HandleConfigImport(AppConfig conf) + { + if (conf == null) return; + + if (conf.BatchCount > 30) + { + Serilog.Log.Debug("对不起,为了项目能长久稳定运行,还是最大不要超过30吧。。。"); + conf.BatchCount = 30; + } + + var updated = await commonService.UpdateConfig(conf); + if (updated) + Serilog.Log.Debug("系统配置导入成功"); + } + + private async Task HandleCookiesImport(List cookies) + { + if (cookies?.Count > 0) + { + var imported = await douyinCookieService.ImportCookies(cookies); + if (imported) + Serilog.Log.Debug("抖音Cookie配置导入成功"); + } + } /// /// 分页查询 /// @@ -181,45 +178,51 @@ namespace dy.net.Controllers [AllowAnonymous] public async Task DeskInitAsync([FromBody] DouyinCookie dyUserCookies) { + // 1. 基础赋值 dyUserCookies.Id = IdGener.GetLong().ToString(); - if (string.IsNullOrWhiteSpace(dyUserCookies.SavePath)) - { - return ApiResult.Fail("收藏存储路径不能为空"); - } - if (!DouyinFileUtils.HasDirectoryReadWritePermission(dyUserCookies.SavePath)) - { - return ApiResult.Fail($"请在飞牛应用设置里面将{dyUserCookies.SavePath}添加读写权限"); - } + // 2. 路径权限校验 + var pathValidationResult = ValidatePaths(dyUserCookies); + if (!pathValidationResult.Success) + return ApiResult.Fail(pathValidationResult.Message); - if (!string.IsNullOrWhiteSpace(dyUserCookies.FavSavePath) && !DouyinFileUtils.HasDirectoryReadWritePermission(dyUserCookies.FavSavePath)) - { - return ApiResult.Fail($"请在飞牛应用设置里面将{dyUserCookies.FavSavePath}添加读写权限"); - } - - if (!string.IsNullOrWhiteSpace(dyUserCookies.UpSavePath) && !DouyinFileUtils.HasDirectoryReadWritePermission(dyUserCookies.UpSavePath)) - { - return ApiResult.Fail($"请在飞牛应用设置里面将{dyUserCookies.UpSavePath}添加读写权限"); - } - - //if (!string.IsNullOrWhiteSpace(dyUserCookies.ImgSavePath) && !DouyinFileUtils.HasDirectoryReadWritePermission(dyUserCookies.ImgSavePath)) - //{ - // return ApiResult.Fail($"请在飞牛应用设置里面将{dyUserCookies.ImgSavePath}添加读写权限"); - //} - - - var checkCk = await httpClientService.CheckCookie(dyUserCookies); - if (!checkCk) - { + // 3. Cookie 有效性校验 + var cookieValid = await httpClientService.CheckCookie(dyUserCookies); + if (!cookieValid) return ApiResult.Fail("Cookie无效,请按照文档提示重新获取有效Cookie,不要使用插件获取cookie"); + + // 4. 保存到数据库 + var saved = await dyCookieService.Add(dyUserCookies); + return saved ? ApiResult.Success() : ApiResult.Fail("添加失败"); + } + + private (bool Success, string Message) ValidatePaths(DouyinCookie cookie) + { + var pathsToCheck = new Dictionary + { + { "收藏存储路径", cookie.SavePath }, + { "喜欢视频存储路径", cookie.FavSavePath }, + { "上传视频存储路径", cookie.UpSavePath }, + // { "图片存储路径", cookie.ImgSavePath } // 可随时启用 + }; + + foreach (var (label, path) in pathsToCheck) + { + if (!string.IsNullOrWhiteSpace(path)) + { + if (!DouyinFileUtils.HasDirectoryReadWritePermission(path)) + { + return (false, $"请在飞牛应用设置里面将 {path} 添加读写权限({label})"); + } + } } - var result = await dyCookieService.Add(dyUserCookies); - if (result) + if (string.IsNullOrWhiteSpace(cookie.SavePath)) { - return ApiResult.Success(); + return (false, "收藏存储路径不能为空"); } - return ApiResult.Fail("添加失败"); + + return (true, string.Empty); } @@ -414,7 +417,7 @@ namespace dy.net.Controllers Path.GetFileNameWithoutExtension(filePath) != "silent_10") .ToList(); - var fileNames = customMusics.Select(f => new {filename= Path.GetFileName(f) }).Where(x=>x.filename!= "silent_10.mp3").ToList(); + var fileNames = customMusics.Select(f => new { filename = Path.GetFileName(f) }).Where(x => x.filename != "silent_10.mp3").ToList(); return ApiResult.Success(fileNames); } else diff --git a/Controllers/FollowController.cs b/Controllers/FollowController.cs index 0eb5b2f..f012908 100644 --- a/Controllers/FollowController.cs +++ b/Controllers/FollowController.cs @@ -3,7 +3,6 @@ using dy.net.model.entity; using dy.net.service; using dy.net.utils; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace dy.net.Controllers @@ -62,7 +61,7 @@ namespace dy.net.Controllers public async Task AddFollow(DouyinFollowed followed) { var res = await _douyinFollowService.AddAsync(followed); - return ApiResult.SuccOrFail(res,"", res ? "" : "添加失败,或者已存在相同secuid和uid"); + return ApiResult.SuccOrFail(res, "", res ? "" : "添加失败,或者已存在相同secuid和uid"); } /// @@ -89,7 +88,7 @@ namespace dy.net.Controllers } } } - var result= await _douyinFollowService.OpenOrCloseSync(dto); + var result = await _douyinFollowService.OpenOrCloseSync(dto); return ApiResult.SuccOrFail(result, result); } @@ -108,7 +107,7 @@ namespace dy.net.Controllers [HttpPost("delete")] public async Task DeleteFollow(FollowUpdateDto dto) { - var result= await _douyinFollowService.DeleteFollow(dto); + var result = await _douyinFollowService.DeleteFollow(dto); return ApiResult.SuccOrFail(result, result); } } diff --git a/Controllers/LogsController.cs b/Controllers/LogsController.cs index a8e696f..9330b30 100644 --- a/Controllers/LogsController.cs +++ b/Controllers/LogsController.cs @@ -1,9 +1,6 @@ using dy.net.model.dto; using dy.net.service; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using System.Net.Http; namespace dy.net.Controllers { @@ -14,14 +11,14 @@ namespace dy.net.Controllers private readonly IWebHostEnvironment webHostEnvironment; private readonly LogInfoService logInfoService; - public LogsController(IWebHostEnvironment webHostEnvironment,LogInfoService logInfoService) + public LogsController(IWebHostEnvironment webHostEnvironment, LogInfoService logInfoService) { this.webHostEnvironment = webHostEnvironment; this.logInfoService = logInfoService; } [HttpGet("/api/logs/GetLog/{type}/{date}")] - public async Task GetLog([FromRoute]string type, [FromRoute] string date) + public async Task GetLog([FromRoute] string type, [FromRoute] string date) { var filePath = Path.Combine(webHostEnvironment.IsDevelopment() ? Directory.GetCurrentDirectory() : AppDomain.CurrentDomain.BaseDirectory, "logs", $"log-{type}-{date}.txt"); if (!System.IO.File.Exists(filePath)) diff --git a/Controllers/VideoController.cs b/Controllers/VideoController.cs index 48ccc13..2d23874 100644 --- a/Controllers/VideoController.cs +++ b/Controllers/VideoController.cs @@ -4,8 +4,6 @@ using dy.net.service; using dy.net.utils; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using System; -using System.Security.Cryptography; namespace dy.net.Controllers { @@ -500,7 +498,7 @@ namespace dy.net.Controllers /// /// 7天图表数据列表 [HttpGet("chart/{day}")] - public async Task Chart([FromRoute]int day=7) + public async Task Chart([FromRoute] int day = 7) { try { @@ -514,7 +512,7 @@ namespace dy.net.Controllers } [HttpGet("/Move")] - public async Task Move() + public async Task Move() { await douyinVideoService.HandOldFolderVideos(); diff --git a/Program.cs b/Program.cs index 31db37b..62875ef 100644 --- a/Program.cs +++ b/Program.cs @@ -1,7 +1,6 @@ using dy.net.extension; using dy.net.service; using dy.net.utils; -using dy.sync.lib; using Serilog; using System.Reflection; using System.Text; @@ -38,7 +37,7 @@ namespace dy.net // 初始化应用服务 InitApplicationServices(app, isDevelopment); Console.WriteLine(); - + app.Run(); } @@ -117,13 +116,13 @@ namespace dy.net /// /// 配置依赖注入服务 /// - private static void ConfigureServices(IServiceCollection services, IConfiguration config, IWebHostEnvironment environment,string dbPath) + private static void ConfigureServices(IServiceCollection services, IConfiguration config, IWebHostEnvironment environment, string dbPath) { //打印logo //PrintApp(); - services.AddSingleton(new Appsettings (config)); + services.AddSingleton(new Appsettings(config)); // 雪花ID生成器 services.AddSnowFlakeId(options => options.WorkId = new Random().Next(1, 100)); @@ -144,7 +143,7 @@ namespace dy.net .AddServicesFromNamespace("dy.net.service"); services.AddScoped(); - + // SPA静态文件支持 services.AddSpaStaticFiles(options => options.RootPath = SpaRootPath); @@ -161,7 +160,7 @@ namespace dy.net services.ConfigureJwtAuthentication(); } - + /// /// 配置中间件 @@ -202,7 +201,7 @@ namespace dy.net /// /// 初始化应用服务数据 /// - private static void InitApplicationServices(WebApplication app,bool isDevelopment) + private static void InitApplicationServices(WebApplication app, bool isDevelopment) { using var scope = app.Services.CreateScope(); var services = scope.ServiceProvider; @@ -211,9 +210,9 @@ namespace dy.net { // 初始化用户 var userService = services.GetRequiredService(); - userService.InitUser("douyin","douyin2026"); + userService.InitUser("douyin", "douyin2026"); var commonService = services.GetRequiredService(); - + // 更新视频类型--兼容老版本--不再需要 //commonService.UpdateCollectViedoType(); // 重置博主作品同步状态为未同步 @@ -227,7 +226,7 @@ namespace dy.net quartzJobService.InitOrReStartAllJobs(config?.Cron <= 0 ? "30" : config.Cron.ToString()); } // 初始化Cookie - var deploy= Appsettings.Get("deploy"); + var deploy = Appsettings.Get("deploy"); if (deploy != null && deploy == "docker")//docker环境直接初始化一个默认的配置 { var cookieService = services.GetRequiredService(); @@ -240,69 +239,5 @@ namespace dy.net } } - - private static void PrintApp() - { - Console.ForegroundColor = ConsoleColor.DarkCyan; - - // 步骤1:定义原始ASCII艺术字行(无缩进) - List originalArtLines = new List - { - " __ __ ", - " ___/ /_ __ ___ __ _____ ____ ___ ___ / /_", - "/ _ / // / (_- indentedArtLines = new List(); - foreach (var line in originalArtLines) - { - indentedArtLines.Add(indent + line); // 每行开头拼接缩进空格 - } - - // 步骤4:找到缩进后最长行的长度(避免越界) - int maxLength = 0; - foreach (var line in indentedArtLines) - { - if (line.Length > maxLength) maxLength = line.Length; - } - - // 步骤5:按列推进打印(从左到右,包含缩进) - for (int col = 0; col < maxLength; col++) - { - Console.SetCursorPosition(0, 0); // 重置光标到第一行开头 - - for (int row = 0; row < indentedArtLines.Count; row++) - { - // 定位到「当前列、当前行」(已包含缩进偏移) - Console.SetCursorPosition(col, row); - - // 打印字符(无字符则补空格) - if (col < indentedArtLines[row].Length) - { - Console.Write(indentedArtLines[row][col]); - } - else - { - Console.Write(' '); - } - } - - Thread.Sleep(20); // 列推进速度(可调整:10=快,50=慢) - } - - // 打印完成后,光标移到艺术字下方 - Console.SetCursorPosition(0, indentedArtLines.Count); - Console.WriteLine(); - Console.ResetColor(); - - } - } } \ No newline at end of file diff --git a/Properties/PublishProfiles/docker.pubxml.user b/Properties/PublishProfiles/docker.pubxml.user index cc030ea..2ca2218 100644 --- a/Properties/PublishProfiles/docker.pubxml.user +++ b/Properties/PublishProfiles/docker.pubxml.user @@ -3,7 +3,7 @@ <_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\ - True|2026-01-23T05:36:48.4086406Z||;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||;True|2026-01-13T22:15:56.9735179+08:00||;True|2026-01-13T22:15:51.8250677+08:00||;False|2026-01-13T22:15:46.6608690+08:00||;True|2026-01-13T22:03:06.4683237+08:00||;False|2026-01-13T22:03:01.2036027+08:00||;True|2026-01-13T21:36:05.8776209+08:00||;True|2026-01-13T21:33:02.0766289+08:00||;False|2026-01-13T21:32:57.1976141+08:00||;True|2026-01-13T19:14:35.2519439+08:00||;True|2026-01-13T15:07:50.0836745+08:00||;False|2026-01-13T15:06:35.5929685+08:00||;True|2026-01-13T10:21:41.6012776+08:00||;True|2026-01-13T09:57:25.4788847+08:00||;True|2026-01-13T09:53:14.4900360+08:00||;True|2026-01-13T09:23:53.6465295+08:00||;True|2026-01-12T22:04:14.5886955+08:00||;False|2026-01-12T22:04:08.2008101+08:00||;True|2026-01-12T21:53:46.9947176+08:00||;True|2026-01-12T21:11:15.8358024+08:00||;True|2026-01-12T21:09:51.8663228+08:00||;True|2026-01-11T21:25:07.5052845+08:00||;False|2026-01-11T21:24:27.5744557+08:00||;True|2026-01-11T19:59:15.4734611+08:00||;False|2026-01-11T19:59:04.9543339+08:00||;True|2026-01-11T18:51:30.6649269+08:00||;True|2026-01-08T21:07:57.5094466+08:00||;True|2026-01-08T14:51:18.2266231+08:00||;True|2026-01-08T14:31:55.1137120+08:00||;True|2026-01-08T00:16:24.4451490+08:00||;True|2026-01-08T00:14:20.7430793+08:00||;True|2026-01-08T00:07:46.7228194+08:00||;True|2026-01-07T23:52:13.3290082+08:00||;True|2026-01-07T23:49:28.4838650+08:00||;True|2026-01-07T23:47:45.1936189+08:00||;True|2026-01-07T23:35:09.7818611+08:00||;True|2026-01-07T23:20:43.7462863+08:00||;True|2026-01-07T23:04:39.5140429+08:00||;False|2026-01-07T23:04:36.5367611+08:00||;True|2026-01-07T22:53:14.6013449+08:00||;True|2026-01-07T22:49:59.9549006+08:00||;True|2026-01-07T22:36:40.0254856+08:00||; + True|2026-01-23T14:14:26.8066324Z||;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||;True|2026-01-13T22:15:56.9735179+08:00||;True|2026-01-13T22:15:51.8250677+08:00||;False|2026-01-13T22:15:46.6608690+08:00||;True|2026-01-13T22:03:06.4683237+08:00||;False|2026-01-13T22:03:01.2036027+08:00||;True|2026-01-13T21:36:05.8776209+08:00||;True|2026-01-13T21:33:02.0766289+08:00||;False|2026-01-13T21:32:57.1976141+08:00||;True|2026-01-13T19:14:35.2519439+08:00||;True|2026-01-13T15:07:50.0836745+08:00||;False|2026-01-13T15:06:35.5929685+08:00||;True|2026-01-13T10:21:41.6012776+08:00||;True|2026-01-13T09:57:25.4788847+08:00||;True|2026-01-13T09:53:14.4900360+08:00||;True|2026-01-13T09:23:53.6465295+08:00||;True|2026-01-12T22:04:14.5886955+08:00||;False|2026-01-12T22:04:08.2008101+08:00||;True|2026-01-12T21:53:46.9947176+08:00||;True|2026-01-12T21:11:15.8358024+08:00||;True|2026-01-12T21:09:51.8663228+08:00||;True|2026-01-11T21:25:07.5052845+08:00||;False|2026-01-11T21:24:27.5744557+08:00||;True|2026-01-11T19:59:15.4734611+08:00||;False|2026-01-11T19:59:04.9543339+08:00||;True|2026-01-11T18:51:30.6649269+08:00||;True|2026-01-08T21:07:57.5094466+08:00||;True|2026-01-08T14:51:18.2266231+08:00||;True|2026-01-08T14:31:55.1137120+08:00||;True|2026-01-08T00:16:24.4451490+08:00||;True|2026-01-08T00:14:20.7430793+08:00||;True|2026-01-08T00:07:46.7228194+08:00||;True|2026-01-07T23:52:13.3290082+08:00||;True|2026-01-07T23:49:28.4838650+08:00||;True|2026-01-07T23:47:45.1936189+08:00||;True|2026-01-07T23:35:09.7818611+08:00||;True|2026-01-07T23:20:43.7462863+08:00||;True|2026-01-07T23:04:39.5140429+08:00||;False|2026-01-07T23:04:36.5367611+08:00||;True|2026-01-07T22:53:14.6013449+08:00||;True|2026-01-07T22:49:59.9549006+08:00||; \ No newline at end of file diff --git a/dy.net.csproj b/dy.net.csproj index 80df3aa..30e62e2 100644 --- a/dy.net.csproj +++ b/dy.net.csproj @@ -73,6 +73,7 @@ + diff --git a/dy.net.csproj.user b/dy.net.csproj.user index 149fbf1..1355007 100644 --- a/dy.net.csproj.user +++ b/dy.net.csproj.user @@ -2,7 +2,7 @@ dy.net - E:\code\dysync\Properties\PublishProfiles\fn.pubxml + E:\code\dysync\Properties\PublishProfiles\docker.pubxml ApiControllerEmptyScaffolder root/Common/Api diff --git a/extension/DouyinExceptionFilter.cs b/extension/DouyinExceptionFilter.cs index 4005c31..b862b1f 100644 --- a/extension/DouyinExceptionFilter.cs +++ b/extension/DouyinExceptionFilter.cs @@ -1,7 +1,6 @@ using dy.net.model.dto; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; -using System.Net; namespace dy.net.extension { diff --git a/extension/EnumExtensions.cs b/extension/EnumExtensions.cs index 6f02813..65c13f2 100644 --- a/extension/EnumExtensions.cs +++ b/extension/EnumExtensions.cs @@ -52,7 +52,7 @@ namespace dy.net.extension public static VideoTypeEnum? ToVideoTypeEnum(this string value) { - if(int.TryParse(value, out int intValue)) + if (int.TryParse(value, out int intValue)) { return ToVideoTypeEnum(intValue); } diff --git a/extension/ServiceExtension.cs b/extension/ServiceExtension.cs index 22a7b83..aff4b4b 100644 --- a/extension/ServiceExtension.cs +++ b/extension/ServiceExtension.cs @@ -1,10 +1,6 @@ -using dy.net.job; -using dy.net.service; +using dy.net.service; using dy.net.utils; using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Mvc.ApiExplorer; -using Microsoft.AspNetCore.Mvc.Authorization; -using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.IdentityModel.Tokens; //using Microsoft.OpenApi.Models; @@ -19,7 +15,6 @@ using SqlSugar; //using Swashbuckle.AspNetCore.SwaggerGen; //using Swashbuckle.AspNetCore.SwaggerUI; using System.IO.Compression; -using System.Net.Http; using System.Net.Security; using System.Reflection; using System.Text; @@ -62,12 +57,12 @@ namespace dy.net.extension // return connectionString; //} - private static string CreateSqliteDBConn(string dbPath="") + private static string CreateSqliteDBConn(string dbPath = "") { - string fileFloder= Path.Combine(Environment.CurrentDirectory, "db"); + string fileFloder = Path.Combine(Environment.CurrentDirectory, "db"); if (!string.IsNullOrEmpty(dbPath)) - { - fileFloder= Path.Combine(dbPath, "db"); + { + fileFloder = Path.Combine(dbPath, "db"); FnDataFolder = Path.Combine(dbPath, "mp3"); if ((!Directory.Exists(FnDataFolder))) { @@ -78,8 +73,8 @@ namespace dy.net.extension { if (Appsettings.Get("deploy") == "fn") { - Log.Error($"fn--dbpath,未正常获取到,请进Q群联系作者 759876963"); - throw new Exception("fn--dbpath,未正常获取到,请进Q群联系作者 759876963"); + Log.Error($"fn--dbpath,未正常获取到,请进Q群联系作者 759876963"); + throw new Exception("fn--dbpath,未正常获取到,请进Q群联系作者 759876963"); } } @@ -136,14 +131,14 @@ namespace dy.net.extension }); } - public static void AddSqlsugar(this IServiceCollection services,string dbpath) + public static void AddSqlsugar(this IServiceCollection services, string dbpath) { //DbType dbtype = GetDBType(configuration); services.AddScoped(db => { var sqlSugar = new SqlSugarClient(new ConnectionConfig { - ConnectionString = CreateSqliteDBConn( dbpath), + ConnectionString = CreateSqliteDBConn(dbpath), InitKeyType = InitKeyType.Attribute, DbType = DbType.Sqlite, IsAutoCloseConnection = true // close connection after each operation (recommended) diff --git a/job/DependencyJobListener.cs b/job/DependencyJobListener.cs deleted file mode 100644 index 4a818f1..0000000 --- a/job/DependencyJobListener.cs +++ /dev/null @@ -1,111 +0,0 @@ -using dy.net.model.dto; -using dy.net.service; -using Quartz; -using Serilog; -using static Quartz.Logging.OperationName; - -namespace dy.net.job -{ - - // /// - ///// 抖音任务依赖监听器(独立公共类) - ///// 作用:监听任务执行完成事件,触发下一个依赖任务,实现顺序执行 - ///// - // public class DouyinJobDependencyListener : IJobListener - // { - // // 监听器名称(唯一标识,不可重复) - // public string Name => "DouyinJobDependencyListener"; - - // /// - // /// 任务配置字典(从外部注入) - // /// - // private readonly Dictionary _jobConfigs; - - // /// - // /// 任务依赖关系(从外部注入,定义执行顺序) - // /// - // private readonly Dictionary _jobDependency; - - // /// - // /// 任务服务(用于触发下一个任务,从外部注入) - // /// - // private readonly DouyinQuartzJobService _jobService; - - // /// - // /// 构造函数(依赖注入) - // /// - // /// 任务配置 - // /// 任务依赖关系 - // /// 任务服务 - // public DouyinJobDependencyListener( - // Dictionary jobConfigs, - // Dictionary jobDependency, - // DouyinQuartzJobService jobService) - // { - // _jobConfigs = jobConfigs ?? throw new ArgumentNullException(nameof(jobConfigs), "任务配置不能为空"); - // _jobDependency = jobDependency ?? throw new ArgumentNullException(nameof(jobDependency), "任务依赖关系不能为空"); - // _jobService = jobService ?? throw new ArgumentNullException(nameof(jobService), "任务服务不能为空"); - // } - - // /// - // /// 任务执行前触发(无需处理) - // /// - // public Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default) - // { - // return Task.CompletedTask; - // } - - // /// - // /// 任务被否决执行时触发(无需处理) - // /// - // public Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default) - // { - // return Task.CompletedTask; - // } - - // /// - // /// 任务执行完成后触发(核心逻辑:触发下一个依赖任务) - // /// - // public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException? jobException, CancellationToken cancellationToken = default) - // { - // var currentJobKey = context.JobDetail.Key; - // Log.Information("【任务监听】任务执行完成 - 任务名称: {JobName}, 执行状态: {Status}", - // currentJobKey.Name, jobException == null ? "成功" : "失败"); - - // // 1. 若当前任务执行失败,终止后续依赖任务(避免无效执行) - // if (jobException != null) - // { - // Log.Error(jobException, "【任务监听】任务 {JobName} 执行失败,终止后续任务链条", currentJobKey.Name); - // return; - // } - - // // 2. 根据当前任务的 JobKey,找到对应的配置 Key(如:dy.job.key.collect → collect) - // var currentConfigKey = _jobConfigs.FirstOrDefault(kv => kv.Value.JobKey == currentJobKey.Name).Key; - // if (string.IsNullOrEmpty(currentConfigKey)) - // { - // Log.Warning("【任务监听】未找到任务 {JobName} 的配置信息,任务链条终止", currentJobKey.Name); - // return; - // } - - // // 3. 查找下一个依赖任务的配置 Key - // if (!_jobDependency.TryGetValue(currentConfigKey, out var nextConfigKey) || string.IsNullOrEmpty(nextConfigKey)) - // { - // Log.Information("【任务监听】任务 {JobName} 是最后一个任务,本次任务链条执行完毕", currentJobKey.Name); - // return; - // } - - // // 4. 触发下一个任务(标记为「依赖触发」,立即执行) - // Log.Information("【任务监听】准备触发下一个任务: {NextJobName}(依赖触发)", nextConfigKey); - // var triggerSuccess = await _jobService.StartJobAsync(nextConfigKey, "", isDependencyTrigger: true); - - // if (triggerSuccess) - // { - // Log.Information("【任务监听】下一个任务 {NextJobName} 触发成功", nextConfigKey); - // } - // else - // { - // Log.Error("【任务监听】下一个任务 {NextJobName} 触发失败,任务链条中断", nextConfigKey); - // } - // } - // } -} diff --git a/job/DouYinCollectSyncJob.cs b/job/DouYinCollectSyncJob.cs index 6a01f48..1a114f2 100644 --- a/job/DouYinCollectSyncJob.cs +++ b/job/DouYinCollectSyncJob.cs @@ -3,8 +3,6 @@ using dy.net.model.entity; using dy.net.model.response; using dy.net.service; using dy.net.utils; -using Serilog; -using System; namespace dy.net.job { @@ -21,7 +19,7 @@ namespace dy.net.job if (now.Hour == 1 && now.Minute < 30) { LogFileCleaner.CleanOldLogFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs"), 1); - await Task.Delay(200); + await Task.Delay(200); } } diff --git a/job/DouYinFavoritSyncJob.cs b/job/DouYinFavoritSyncJob.cs index a8323ac..2471fb5 100755 --- a/job/DouYinFavoritSyncJob.cs +++ b/job/DouYinFavoritSyncJob.cs @@ -22,10 +22,10 @@ namespace dy.net.job protected override async Task> GetSyncCookies() { - return await douyinCookieService.GetOpendCookiesAsync(x=> !string.IsNullOrWhiteSpace(x.FavSavePath)&&!string.IsNullOrWhiteSpace(x.SecUserId)); + return await douyinCookieService.GetOpendCookiesAsync(x => !string.IsNullOrWhiteSpace(x.FavSavePath) && !string.IsNullOrWhiteSpace(x.SecUserId)); } - protected override async Task FetchVideoData(DouyinCookie cookie, string cursor,DouyinFollowed followed, DouyinCollectCate cate) + protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed, DouyinCollectCate cate) { return await douyinHttpClientService.SyncFavoriteVideos(count, cursor, cookie.SecUserId, cookie.Cookies); } @@ -43,7 +43,7 @@ namespace dy.net.job // await base.HandleSyncCompletion(cookie, syncCount, followed, cate); //} - 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; if (string.IsNullOrWhiteSpace(item.Author?.Nickname) && string.IsNullOrWhiteSpace(item.Author?.Uid)) diff --git a/job/DouyinBasicSyncJob.cs b/job/DouyinBasicSyncJob.cs index f0c4461..8db944d 100644 --- a/job/DouyinBasicSyncJob.cs +++ b/job/DouyinBasicSyncJob.cs @@ -188,7 +188,7 @@ namespace dy.net.job ///// 关注博主 ///// 如果应该继续同步,则为true;否则为false //protected bool ShouldContinueSync(DouyinCookie cookie, DouyinVideoInfoResponse data, DouyinFollowed followed, AppConfig config) { - + //} /// @@ -211,7 +211,7 @@ namespace dy.net.job /// /// 应用配置 /// 创建的视频保存文件夹路径 - protected virtual string CreateSaveFolder(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed,DouyinCollectCate cate) + protected virtual string CreateSaveFolder(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed, DouyinCollectCate cate) { var folder = Path.Combine(cookie.SavePath, DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId, true)); if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); @@ -260,12 +260,12 @@ namespace dy.net.job /// /// /// 一个表示异步操作的任务 - protected async Task HandleSyncCompletion(DouyinCookie cookie, int syncCount, DouyinFollowed followed = null,DouyinCollectCate cate=null) + protected async Task HandleSyncCompletion(DouyinCookie cookie, int syncCount, DouyinFollowed followed = null, DouyinCollectCate cate = null) { var tag = cate?.Name ?? followed?.UperName ?? string.Empty; tag = !string.IsNullOrWhiteSpace(tag) ? $"-[{tag}]" : tag; Log.Debug($"[{VideoType.GetDesc()}][{cookie.UserName}]{tag},本次成功同步{syncCount}条视频"); - + if (cate != null) { //更新合集短剧完结状态 @@ -359,7 +359,7 @@ namespace dy.net.job bool hasMore = true; (syncCount, cursor, hasMore) = await GetAndSaveViedos(cookie, config, syncCount, cursor, hasMore, null, cate); await HandleSyncCompletion(cookie, syncCount, null); - + } } else @@ -388,7 +388,7 @@ namespace dy.net.job { // 获取视频数据 var data = await FetchVideoData(cookie, cursor, followed, cate); - if (data == null|| data.AwemeList == null || !data.AwemeList.Any()) + if (data == null || data.AwemeList == null || !data.AwemeList.Any()) { Serilog.Log.Debug($"[{VideoType.GetDesc()}][{cookie.UserName}] 没有新的视频"); break; @@ -402,8 +402,8 @@ namespace dy.net.job hasMore = data.HasMore == 1; // 处理视频列表 - (List videos,int syncCountx) = await ProcessVideoList(syncCount,cookie, data, config, followed, cate); - if(videos != null && videos.Any()) + (List videos, int syncCountx) = await ProcessVideoList(syncCount, cookie, data, config, followed, cate); + if (videos != null && videos.Any()) { // 保存视频信息到数据库 await SaveVideos(videos); @@ -411,7 +411,7 @@ namespace dy.net.job syncCount += syncCountx; - if (IsSyncLimitReached(cookie, config, syncCount,cate,followed)) + if (IsSyncLimitReached(cookie, config, syncCount, cate, followed)) { break; } @@ -432,9 +432,9 @@ namespace dy.net.job /// /// /// 是否需要终止循环 - private bool IsSyncLimitReached(DouyinCookie cookie, AppConfig config, int syncCount,DouyinCollectCate cate,DouyinFollowed followed) + private bool IsSyncLimitReached(DouyinCookie cookie, AppConfig config, int syncCount, DouyinCollectCate cate, DouyinFollowed followed) { - if(cate!=null && cate.CateType != VideoTypeEnum.dy_custom_collect) + if (cate != null && cate.CateType != VideoTypeEnum.dy_custom_collect) { if (syncCount >= 15) { @@ -481,7 +481,7 @@ namespace dy.net.job /// 关注的 /// 收藏夹、合集、短剧 /// 处理后的视频实体列表 - protected async Task<(List videos,int currentCount)> ProcessVideoList(int syncCount1,DouyinCookie cookie, DouyinVideoInfoResponse data, AppConfig config, DouyinFollowed followed = null, DouyinCollectCate cate = null) + protected async Task<(List videos, int currentCount)> ProcessVideoList(int syncCount1, DouyinCookie cookie, DouyinVideoInfoResponse data, AppConfig config, DouyinFollowed followed = null, DouyinCollectCate cate = null) { int syncCount = 0; var videos = new List(); @@ -507,7 +507,7 @@ namespace dy.net.job } if (cate == null) { - + bool Goon = await AutoDistinct(config, exitVideo); if (!Goon) @@ -533,15 +533,15 @@ namespace dy.net.job } } // 处理单个视频 - var video = await ProcessSingleVideo(cookie, item, data, config, followed,cate); + var video = await ProcessSingleVideo(cookie, item, data, config, followed, cate); if (video != null) { videos.Add(video); syncCount++; - if (syncCount+ syncCount1 >= config.BatchCount) + if (syncCount + syncCount1 >= config.BatchCount) { - return (videos,syncCount); + return (videos, syncCount); } } else @@ -579,7 +579,7 @@ namespace dy.net.job if (dynamicVideoUrls.Count > 0) { // 处理动态视频 - var dynamicVideo = await ProcessDynamicVideo(dynamicVideoUrls, cookie, item, config,followed,cate); + var dynamicVideo = await ProcessDynamicVideo(dynamicVideoUrls, cookie, item, config, followed, cate); if (dynamicVideo != null) { if (!string.IsNullOrEmpty(dynamicVideo.DynamicVideos)) @@ -620,7 +620,7 @@ namespace dy.net.job } videos.Add(dynamicVideo); syncCount++; - if (syncCount+ syncCount1 >= config.BatchCount) + if (syncCount + syncCount1 >= config.BatchCount) { return (videos, syncCount); } @@ -640,7 +640,7 @@ namespace dy.net.job { videos.Add(mergevideo); syncCount++; - if (syncCount+ syncCount1 >= config.BatchCount) + if (syncCount + syncCount1 >= config.BatchCount) { return (videos, syncCount); } @@ -814,8 +814,6 @@ namespace dy.net.job var videoUrl = v.PlayAddr.UrlList.Where(x => !string.IsNullOrEmpty(x))?.FirstOrDefault(); if (string.IsNullOrWhiteSpace(videoUrl)) return null; - // 获取视频标签 - var (tag1, tag2, tag3) = GetVideoTags(item); // 创建保存文件夹 var saveFolder = CreateSaveFolder(cookie, item, config, followed, cate); // 获取视频文件名 @@ -851,12 +849,12 @@ namespace dy.net.job Log.Debug($"[{VideoType.GetDesc()}][{item?.Author?.Nickname ?? ""}]-视频[{DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId)}]下载完成."); } // 下载视频封面 - await GetDownVideoCover(item, saveFolder, cookie, config,cate); + await GetDownVideoCover(item, saveFolder, cookie, config, cate); // 下载作者头像 var (avatarSavePath, avatarUrl) = await DownAuthorAvatar(cookie, item); // 创建视频实体 - return await CreateVideoEntity(config, cookie, item, v, savePath, saveFolder, tag1, tag2, tag3, avatarUrl, avatarSavePath, null, cate); + return await CreateVideoEntity(config, cookie, item, v, savePath, saveFolder, avatarSavePath, null, cate); } /// @@ -869,12 +867,8 @@ namespace dy.net.job /// /// /// - protected async Task ProcessDynamicVideo(List dynamicUrls, DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed = null,DouyinCollectCate cate=null) + protected async Task ProcessDynamicVideo(List dynamicUrls, DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed = null, DouyinCollectCate cate = null) { - - - // 获取视频标签 - var (tag1, tag2, tag3) = GetVideoTags(item); // 创建保存文件夹 var saveFolder = CreateSaveFolder(cookie, item, config, followed, cate); // 获取视频文件名 @@ -921,7 +915,7 @@ namespace dy.net.job //await DownVideoCover(item, saveFolder, cookie, config); //// 下载作者头像 var (avatarSavePath, avatarUrl) = await DownAuthorAvatar(cookie, item); - + // 创建视频实体 var virtualBitRate = new VideoBitRate { @@ -932,7 +926,7 @@ namespace dy.net.job DataSize = DouyinFileUtils.GetTotalFileSize(dynamicSavePaths.Select(x => x.Path).ToList()) // 合成视频的文件大小 } }; - return await CreateVideoEntity(config, cookie, item, virtualBitRate, dynamicSavePaths.FirstOrDefault()?.Path, saveFolder, tag1, tag2, tag3, avatarUrl, avatarSavePath, dynamicSavePaths,cate); + return await CreateVideoEntity(config, cookie, item, virtualBitRate, dynamicSavePaths.FirstOrDefault()?.Path, saveFolder, avatarSavePath, dynamicSavePaths, cate); } @@ -1003,7 +997,7 @@ namespace dy.net.job /// 应用配置 /// /// 合成后的视频实体,如果处理失败则为null - protected async Task ProcessImageSetAndMergeToVideo(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed,DouyinCollectCate cate) + protected async Task ProcessImageSetAndMergeToVideo(DouyinCookie cookie, Aweme item, AppConfig config, DouyinFollowed followed, DouyinCollectCate cate) { try { @@ -1027,7 +1021,7 @@ namespace dy.net.job if (!Directory.Exists(fileNamefolder)) Directory.CreateDirectory(fileNamefolder); - var fileName = GetVideoFileName(cookie, item, config,cate); + var fileName = GetVideoFileName(cookie, item, config, cate); // 合成视频的保存路径 var savePath = Path.Combine(fileNamefolder, fileName); @@ -1090,16 +1084,14 @@ namespace dy.net.job } var coverUrl = cate is not null && cate.CateType != VideoTypeEnum.dy_custom_collect - ? item.Music?.CoverHd?.UrlList?.FirstOrDefault() ?? imageUrls.FirstOrDefault() + ? (item.MixInfo?.CoverUrl?.UrlList?.FirstOrDefault() ?? imageUrls.FirstOrDefault() ?? item.Music?.CoverHd?.UrlList?.FirstOrDefault()) : imageUrls.FirstOrDefault(); // 下载视频封面(使用第一张图片作为封面) - if(!string.IsNullOrWhiteSpace(coverUrl)) - await DownVideoCover(coverUrl, fileNamefolder, cookie, item, config,cate); + if (!string.IsNullOrWhiteSpace(coverUrl)) + await DownVideoCover(coverUrl, fileNamefolder, cookie, item, config, cate); // 下载作者头像 var (avatarSavePath, avatarUrl) = await DownAuthorAvatar(cookie, item); - // 获取视频标签 - var (tag1, tag2, tag3) = GetVideoTags(item); // 为合成的视频创建一个“虚拟”的BitRate对象,以便复用CreateVideoEntity方法 var virtualBitRate = new VideoBitRate { @@ -1113,8 +1105,7 @@ namespace dy.net.job // 创建视频实体 var videoEntity = await CreateVideoEntity(config, - cookie, item, virtualBitRate, savePath, fileNamefolder, - tag1, tag2, tag3, avatarUrl,avatarSavePath, null,cate); + cookie, item, virtualBitRate, savePath, fileNamefolder, avatarSavePath, null, cate); // 特殊处理合成视频的字段 videoEntity.FileHash = string.Empty; // 合成视频没有原始文件哈希 @@ -1164,7 +1155,7 @@ namespace dy.net.job /// 应用配置 /// /// 一个表示异步操作的任务 - protected async Task GetDownVideoCover(Aweme item, string saveFolder, DouyinCookie cookie, AppConfig config,DouyinCollectCate cate) + protected async Task GetDownVideoCover(Aweme item, string saveFolder, DouyinCookie cookie, AppConfig config, DouyinCollectCate cate) { // 定义封面URL变量 string coverUrl; @@ -1174,8 +1165,8 @@ namespace dy.net.job { // cate不为空时:优先MixInfo封面 → 其次Music高清封面 → 最后Video封面 coverUrl = item.MixInfo?.CoverUrl?.UrlList?.FirstOrDefault() - ?? item.Music?.CoverHd?.UrlList?.FirstOrDefault() - ?? item.Video.Cover.UrlList?.FirstOrDefault(); + ?? item.Video.Cover.UrlList?.LastOrDefault() + ?? item.Music?.CoverHd?.UrlList?.FirstOrDefault(); } else { @@ -1294,7 +1285,7 @@ namespace dy.net.job /// 应用配置 /// /// 一个表示异步操作的任务 - private async Task DownVideoCover(string coverUrl, string saveFolder, DouyinCookie cookie, Aweme item, AppConfig config,DouyinCollectCate cate) + private async Task DownVideoCover(string coverUrl, string saveFolder, DouyinCookie cookie, Aweme item, AppConfig config, DouyinCollectCate cate) { if (string.IsNullOrWhiteSpace(coverUrl)) return; // 获取封面图片文件名 @@ -1318,18 +1309,15 @@ namespace dy.net.job /// 视频码率信息 /// 视频保存路径 /// 视频保存文件夹 - /// 视频标签1 - /// 视频标签2 - /// 视频标签3 - /// /// /// 动态视频 /// 短剧、合集、自定义收藏夹 /// 创建的视频实体对象 private async Task CreateVideoEntity(AppConfig config, - DouyinCookie cookie, Aweme item, VideoBitRate bitRate, string savePath, string saveFolder, - string tag1, string tag2, string tag3,string avatorUrl,string avatorPath, List dynamicVideos = null,DouyinCollectCate cate=null) + DouyinCookie cookie, Aweme item, VideoBitRate bitRate, string savePath, string saveFolder, string avatorPath, List dynamicVideos = null, DouyinCollectCate cate = null) { + // 获取视频标签 + var (tag1, tag2, tag3) = GetVideoTags(item); var video = new DouyinVideo { ViedoType = VideoType, @@ -1356,12 +1344,12 @@ namespace dy.net.job DyUserId = item.AuthorUserId == 0 ? item.Author?.Uid : item.AuthorUserId.ToString(), CookieId = cookie.Id, OnlyImgOrOnlyMp3 = string.IsNullOrWhiteSpace(savePath) && !config.DownImageVideo && (config.DownImage || config.DownMp3), - CateId= cate?.Id, - CateXId= cate?.XId, + CateId = cate?.Id, + CateXId = cate?.XId, }; if (cate != null && cate.CateType != VideoTypeEnum.dy_custom_collect) { - video.VideoTitle = (string.IsNullOrWhiteSpace(item.Desc) ? cate.Name : $"[{cate.Name}]"+"_"+item.Desc) + "_" + item.MixInfo.Statis.CurrentEpisode; + video.VideoTitle = (string.IsNullOrWhiteSpace(item.Desc) ? cate.Name : $"[{cate.Name}]" + "_" + item.Desc) + "_" + item.MixInfo.Statis.CurrentEpisode; } if (dynamicVideos != null && dynamicVideos.Count > 0) { diff --git a/job/DouyinCollectCustomSyncJob.cs b/job/DouyinCollectCustomSyncJob.cs index 2f17854..e022534 100644 --- a/job/DouyinCollectCustomSyncJob.cs +++ b/job/DouyinCollectCustomSyncJob.cs @@ -3,7 +3,6 @@ using dy.net.model.entity; using dy.net.model.response; using dy.net.service; using dy.net.utils; -using System; namespace dy.net.job { @@ -25,7 +24,7 @@ namespace dy.net.job } else { - return base.CreateSaveFolder(cookie, item, config,followed,cate); + return base.CreateSaveFolder(cookie, item, config, followed, cate); } } protected override string GetAuthorAvatarBasePath(DouyinCookie cookie) @@ -35,7 +34,7 @@ namespace dy.net.job protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed, DouyinCollectCate cate) { - return await douyinHttpClientService.SyncCollectVideosByCollectId(cursor,count,cookie.Cookies,cate.XId); + return await douyinHttpClientService.SyncCollectVideosByCollectId(cursor, count, cookie.Cookies, cate.XId); } //protected override bool ShouldContinueSync(DouyinCookie cookie, DouyinVideoInfoResponse data, DouyinFollowed followed = null) diff --git a/job/DouyinFollowedSyncJob.cs b/job/DouyinFollowedSyncJob.cs index f1a3619..a2e8209 100644 --- a/job/DouyinFollowedSyncJob.cs +++ b/job/DouyinFollowedSyncJob.cs @@ -4,10 +4,6 @@ using dy.net.model.entity; using dy.net.model.response; using dy.net.service; using dy.net.utils; -using Newtonsoft.Json; -using System.IO; -using System.Linq; -using System.Threading.Tasks; namespace dy.net.job { @@ -21,10 +17,10 @@ namespace dy.net.job protected override async Task> GetSyncCookies() { - return await douyinCookieService.GetOpendCookiesAsync(x => !string.IsNullOrWhiteSpace(x.UpSavePath)); + return await douyinCookieService.GetOpendCookiesAsync(x => !string.IsNullOrWhiteSpace(x.UpSavePath)); } - protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed,DouyinCollectCate cate) + protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed, DouyinCollectCate cate) { return await douyinHttpClientService.SyncUpderPostVideos(count, cursor, followed.SecUid, cookie.Cookies); } @@ -47,7 +43,7 @@ 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) { #region 默认使用UP主名称作为文件夹名称,若关注列表中有自定义保存路径则使用自定义路径 // 1. 优先获取有效的作者名称(遵循原有优先级:followed.UperName > item.Author.Nickname > 默认值) @@ -75,14 +71,14 @@ namespace dy.net.job /// /// /// - protected override string GetVideoFileName(DouyinCookie cookie, Aweme item,AppConfig config,DouyinCollectCate cate) + protected override string GetVideoFileName(DouyinCookie cookie, Aweme item, AppConfig config, DouyinCollectCate cate) { - + string Format = "mp4"; string FileHash = ""; string Height = ""; string Width = ""; - + if (item.Video != null && item.Video.BitRate != null) { var bitrate = item.Video.BitRate.FirstOrDefault(); @@ -95,8 +91,9 @@ namespace dy.net.job { //图片合成视频,参数要自己写。 var image = item.Images?.FirstOrDefault(); - if(image != null){ - FileHash = IdGener.GetGuid().ToLower().Replace("-","");//使用随机值,避免重复 + if (image != null) + { + FileHash = IdGener.GetGuid().ToLower().Replace("-", "");//使用随机值,避免重复 Height = image.Height.ToString(); Width = image.Width.ToString(); } @@ -113,24 +110,24 @@ namespace dy.net.job //else //{ - if (!string.IsNullOrWhiteSpace(config.FullFollowedTitleTemplate)) + if (!string.IsNullOrWhiteSpace(config.FullFollowedTitleTemplate)) + { + var fullName = VideoTitleGenerator.Generate(config.FullFollowedTitleTemplate, new VideoTitleDataTemplate { - var fullName = VideoTitleGenerator.Generate(config.FullFollowedTitleTemplate, new VideoTitleDataTemplate - { - FileHash = FileHash, - Id = item.AwemeId, - ReleaseTime = DateTimeUtil.Convert10BitTimestamp(item.CreateTime), - Resolution = $"{Width}×{Height}", - VideoTitle = DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId), - Author = item.Author.Nickname - }); + FileHash = FileHash, + Id = item.AwemeId, + ReleaseTime = DateTimeUtil.Convert10BitTimestamp(item.CreateTime), + Resolution = $"{Width}×{Height}", + VideoTitle = DouyinFileNameHelper.SanitizeLinuxFileName(item.Desc, item.AwemeId), + Author = item.Author.Nickname + }); - fileName= $"{fullName}.{Format}"; - } - else - { - fileName = $"{item.AwemeId}.{Format}"; - } + fileName = $"{fullName}.{Format}"; + } + else + { + fileName = $"{item.AwemeId}.{Format}"; + } //} return fileName; @@ -146,7 +143,7 @@ namespace dy.net.job /// /// /// - protected override string GetNfoFileName(DouyinCookie cookie, Aweme item, AppConfig config, string imageType,DouyinCollectCate cate) + protected override string GetNfoFileName(DouyinCookie cookie, Aweme item, AppConfig config, string imageType, DouyinCollectCate cate) { return base.GetNfoFileName(cookie, item, config, imageType, cate); } @@ -158,6 +155,6 @@ namespace dy.net.job // await base.HandleSyncCompletion(cookie, syncCount, followed, cate); //} - + } } \ No newline at end of file diff --git a/job/DouyinFollowsAndCollnectsSyncJob.cs b/job/DouyinFollowsAndCollnectsSyncJob.cs index bd0ad35..5257be0 100644 --- a/job/DouyinFollowsAndCollnectsSyncJob.cs +++ b/job/DouyinFollowsAndCollnectsSyncJob.cs @@ -4,10 +4,6 @@ using dy.net.model.response; using dy.net.service; using Quartz; using Serilog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace dy.net.job { diff --git a/job/DouyinMixSyncJob.cs b/job/DouyinMixSyncJob.cs index 0e31f35..d8e9620 100644 --- a/job/DouyinMixSyncJob.cs +++ b/job/DouyinMixSyncJob.cs @@ -16,9 +16,9 @@ namespace dy.net.job protected override VideoTypeEnum VideoType => VideoTypeEnum.dy_mix; - protected override async Task FetchVideoData(DouyinCookie cookie, string cursor,DouyinFollowed followed,DouyinCollectCate cate) + protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed, DouyinCollectCate cate) { - return await douyinHttpClientService.SyncMixViedosByMixId(cursor,count,cookie.Cookies,cate.XId); + return await douyinHttpClientService.SyncMixViedosByMixId(cursor, count, cookie.Cookies, cate.XId); } //protected override bool ShouldContinueSync(DouyinCookie cookie, DouyinVideoInfoResponse data, DouyinFollowed followed=null) @@ -29,7 +29,7 @@ namespace dy.net.job { if (cate != null) { - if(string.IsNullOrWhiteSpace(cookie.MixPath)) + if (string.IsNullOrWhiteSpace(cookie.MixPath)) { var folder = Path.Combine(cookie.SavePath, VideoType.GetDesc(), DouyinFileNameHelper.SanitizeLinuxFileName(cate.SaveFolder, cate.Name, true)); if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); diff --git a/job/DouyinSeriesSyncJob.cs b/job/DouyinSeriesSyncJob.cs index ef4d537..5ac0b77 100644 --- a/job/DouyinSeriesSyncJob.cs +++ b/job/DouyinSeriesSyncJob.cs @@ -3,7 +3,6 @@ using dy.net.model.entity; using dy.net.model.response; using dy.net.service; using dy.net.utils; -using System.Net; namespace dy.net.job { @@ -16,9 +15,9 @@ namespace dy.net.job protected override VideoTypeEnum VideoType => VideoTypeEnum.dy_series; - protected override async Task FetchVideoData(DouyinCookie cookie, string cursor,DouyinFollowed followed, DouyinCollectCate cate) + protected override async Task FetchVideoData(DouyinCookie cookie, string cursor, DouyinFollowed followed, DouyinCollectCate cate) { - return await douyinHttpClientService.SyncSeriesViedosByMSeriesId(cursor, count, cookie.Cookies,cate.XId); + return await douyinHttpClientService.SyncSeriesViedosByMSeriesId(cursor, count, cookie.Cookies, cate.XId); } //protected override bool ShouldContinueSync(DouyinCookie cookie, DouyinVideoInfoResponse data, DouyinFollowed followed=null) diff --git a/model/dto/DouyinResponse.cs b/model/dto/DouyinResponse.cs index 193ded8..aba9d5c 100644 --- a/model/dto/DouyinResponse.cs +++ b/model/dto/DouyinResponse.cs @@ -80,7 +80,7 @@ namespace dy.net.model.dto /// /// /// - public static IActionResult SuccOrFail(int code,T t,string message = "") + public static IActionResult SuccOrFail(int code, T t, string message = "") { if (code == ResponseCode.Success) { @@ -130,7 +130,7 @@ namespace dy.net.model.dto /// 错误消息 /// 附加数据 /// IActionResult - public static IActionResult Fail(string message="请求失败", int businessCode = ResponseCode.ServerError, T data = default) + public static IActionResult Fail(string message = "请求失败", int businessCode = ResponseCode.ServerError, T data = default) { var response = new DouyinApiResponse { @@ -158,7 +158,7 @@ namespace dy.net.model.dto /// /// 错误消息 /// IActionResult - public static IActionResult Fail(string message="请求失败") + public static IActionResult Fail(string message = "请求失败") { return Fail(message, ResponseCode.ServerError); } diff --git a/model/dto/DouyinUpSecUserIdDto.cs b/model/dto/DouyinUpSecUserIdDto.cs index 93926e5..2b2737b 100644 --- a/model/dto/DouyinUpSecUserIdDto.cs +++ b/model/dto/DouyinUpSecUserIdDto.cs @@ -1,6 +1,4 @@ -using Newtonsoft.Json; - -namespace dy.net.model.dto +namespace dy.net.model.dto { public class DouyinUpSecUserIdDto { diff --git a/model/dto/DouyinVideoPageRequestDto.cs b/model/dto/DouyinVideoPageRequestDto.cs index 88c1725..4613b77 100644 --- a/model/dto/DouyinVideoPageRequestDto.cs +++ b/model/dto/DouyinVideoPageRequestDto.cs @@ -1,6 +1,4 @@ -using System.ComponentModel.DataAnnotations; - -namespace dy.net.model.dto +namespace dy.net.model.dto { public class DouyinVideoPageRequestDto : PageRequestDto { @@ -35,7 +33,7 @@ namespace dy.net.model.dto } - public class FollowRequestDto: PageRequestDto + public class FollowRequestDto : PageRequestDto { public string FollowUserName { get; set; } diff --git a/model/dto/MediaMergeRequest.cs b/model/dto/MediaMergeRequest.cs index fb4386e..5367b37 100644 --- a/model/dto/MediaMergeRequest.cs +++ b/model/dto/MediaMergeRequest.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dy.net.model.dto +namespace dy.net.model.dto { public class MediaMergeRequest { diff --git a/model/dto/VideoTypeEnum.cs b/model/dto/VideoTypeEnum.cs index 952fa4c..a4d4c21 100644 --- a/model/dto/VideoTypeEnum.cs +++ b/model/dto/VideoTypeEnum.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; - -namespace dy.net.model.dto +namespace dy.net.model.dto { public enum VideoTypeEnum { diff --git a/model/entity/AdminUserInfo.cs b/model/entity/AdminUserInfo.cs index 0e721aa..b3591e5 100644 --- a/model/entity/AdminUserInfo.cs +++ b/model/entity/AdminUserInfo.cs @@ -1,11 +1,9 @@ -using System.Diagnostics.CodeAnalysis; - -namespace dy.net.model.entity +namespace dy.net.model.entity { [SqlSugar.SugarTable(TableName = "login_user_info")] public class AdminUserInfo { - public string UserName { get; set;} + public string UserName { get; set; } public string Password { get; set; } [SqlSugar.SugarColumn(IsPrimaryKey = true)] @@ -23,7 +21,7 @@ namespace dy.net.model.entity /// /// 原密码,不存在数据库 /// - [SqlSugar.SugarColumn(IsIgnore =true)] + [SqlSugar.SugarColumn(IsIgnore = true)] public string? OldPwd { get; set; } /// diff --git a/model/entity/AppConfig.cs b/model/entity/AppConfig.cs index d320481..fa58a2e 100644 --- a/model/entity/AppConfig.cs +++ b/model/entity/AppConfig.cs @@ -1,6 +1,4 @@ -using Newtonsoft.Json; -using SqlSugar; -using System.Text.RegularExpressions; +using SqlSugar; namespace dy.net.model.entity { @@ -15,10 +13,10 @@ namespace dy.net.model.entity /// /// /// - [SugarColumn(IsPrimaryKey = true,Length =100)] + [SugarColumn(IsPrimaryKey = true, Length = 100)] public string Id { get; set; } - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public int Cron { get; set; } /// @@ -70,7 +68,7 @@ namespace dy.net.model.entity /// //public bool ImageViedoSaveAlone { get; set; } - + /// /// 自动去重-逻辑是遇到相同ID的视频直接跳过 diff --git a/model/entity/DouyinCollectCate.cs b/model/entity/DouyinCollectCate.cs index e3be11f..3acb7d0 100644 --- a/model/entity/DouyinCollectCate.cs +++ b/model/entity/DouyinCollectCate.cs @@ -15,7 +15,7 @@ namespace dy.net.model.entity /// [SugarColumn(IsPrimaryKey = true)] public string Id { get; set; } - + /// /// 关联cookieId /// @@ -29,18 +29,18 @@ namespace dy.net.model.entity /// /// 收藏夹Id、合集Id、短剧Id /// - [SugarColumn(Length =60,IsNullable =false)] + [SugarColumn(Length = 60, IsNullable = false)] public string XId { get; set; } /// /// 封面 /// - [SugarColumn(Length =500,IsNullable =true)] + [SugarColumn(Length = 500, IsNullable = true)] public string CoverUrl { get; set; } /// /// 保存文件夹 /// - [SugarColumn(Length =500,IsNullable =true)] + [SugarColumn(Length = 500, IsNullable = true)] public string SaveFolder { get; set; } /// /// 是否开启同步 @@ -52,9 +52,9 @@ namespace dy.net.model.entity /// public VideoTypeEnum CateType { get; set; } - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } - [SugarColumn(IsNullable =true)] + [SugarColumn(IsNullable = true)] public DateTime? UpdateTime { get; set; } /// /// 是否已完结 diff --git a/model/entity/DouyinCookie.cs b/model/entity/DouyinCookie.cs index 6becf92..1d51891 100644 --- a/model/entity/DouyinCookie.cs +++ b/model/entity/DouyinCookie.cs @@ -32,16 +32,16 @@ namespace dy.net.model.entity /// /// 是否按收藏夹文件夹来存储视频 /// - public bool UseCollectFolder { get; set; } + public bool UseCollectFolder { get; set; } /// /// 是否下载合集 /// - public bool DownMix { get; set; } + public bool DownMix { get; set; } /// /// 是否下载短剧 /// - public bool DownSeries { get; set; } + public bool DownSeries { get; set; } /// /// 1 开启同步 0 关闭同步 /// diff --git a/model/entity/DouyinFollowed.cs b/model/entity/DouyinFollowed.cs index 6e85063..bbb070f 100644 --- a/model/entity/DouyinFollowed.cs +++ b/model/entity/DouyinFollowed.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using SqlSugar; +using SqlSugar; namespace dy.net.model.entity { @@ -18,18 +17,18 @@ namespace dy.net.model.entity /// /// 博主sec_uid /// - [SugarColumn(IsNullable = false,Length =500)] + [SugarColumn(IsNullable = false, Length = 500)] public string SecUid { get; set; } - [SugarColumn(IsNullable = false, Length =200)] + [SugarColumn(IsNullable = false, Length = 200)] public string UperName { get; set; } - [SugarColumn(IsNullable = true, Length =1000)] + [SugarColumn(IsNullable = true, Length = 1000)] public string UperAvatar { get; set; } /// /// 官方账号(企业认证) /// - [SugarColumn(IsNullable = true, Length =200)] + [SugarColumn(IsNullable = true, Length = 200)] public string Enterprise { get; set; } /// /// 是否开启同步 @@ -47,25 +46,25 @@ namespace dy.net.model.entity /// /// 我的userId,关注者的抖音userid /// - [SugarColumn(IsNullable = false,Length =200)] + [SugarColumn(IsNullable = false, Length = 200)] public string mySelfId { get; set; } /// /// 签名 /// - [SugarColumn(IsNullable = true,Length =500)] + [SugarColumn(IsNullable = true, Length = 500)] public string Signature { get; set; } /// /// 同步文件保存路径 /// - [SugarColumn(IsNullable = true,Length =500)] + [SugarColumn(IsNullable = true, Length = 500)] public string SavePath { get; set; } /// /// 博主Id /// - [SugarColumn(IsNullable = true,Length =100)] + [SugarColumn(IsNullable = true, Length = 100)] public string UperId { get; set; } /// diff --git a/model/entity/DouyinReDownload.cs b/model/entity/DouyinReDownload.cs index 0fc88eb..406dd5f 100644 --- a/model/entity/DouyinReDownload.cs +++ b/model/entity/DouyinReDownload.cs @@ -16,12 +16,12 @@ namespace dy.net.model.entity /// /// 原视频Id /// - [SugarColumn(IsNullable =true,Length =50)] + [SugarColumn(IsNullable = true, Length = 50)] public string ViedoId { get; set; } /// /// 原保存目录 /// - [SugarColumn(IsNullable =true,Length =1000)] + [SugarColumn(IsNullable = true, Length = 1000)] public string SavePath { get; set; } public string CookieId { get; set; } diff --git a/model/entity/DouyinVideo.cs b/model/entity/DouyinVideo.cs index a8c5b02..8e2bc97 100644 --- a/model/entity/DouyinVideo.cs +++ b/model/entity/DouyinVideo.cs @@ -1,5 +1,4 @@ -using dy.net.extension; -using dy.net.model.dto; +using dy.net.model.dto; using dy.net.utils; using SqlSugar; @@ -15,17 +14,17 @@ namespace dy.net.model.entity [SugarColumn(IsPrimaryKey = true)] public string Id { get; set; } - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string DyUserId { get; set; } - [SugarColumn(IsIgnore =true)] + [SugarColumn(IsIgnore = true)] public string DyUser { get; set; } - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string CookieId { get; set; } /// /// aweme_id /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string AwemeId { get; set; } public DateTime SyncTime { get; set; } @@ -34,34 +33,34 @@ namespace dy.net.model.entity /// /// 视频标题 /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string VideoTitle { get; set; } /// /// 如果配置文件 UperFileNameUseViedoTitle=true /// 简化后的标题 默认空 只有关注的博主的 视频会存储该字段,实际UP主的视频文件名是 VideoTitleSimplify + VideoTitleSimplifyPrefix /// - [SugarColumn(Length =500,IsNullable =true)] + [SugarColumn(Length = 500, IsNullable = true)] public string VideoTitleSimplify { get; set; } /// /// 精简标题的前缀 默认空,其实就是序号,类似 001-,002- /// - [SugarColumn(Length =50,IsNullable =true)] + [SugarColumn(Length = 50, IsNullable = true)] public string VideoTitleSimplifyPrefix { get; set; } /// /// 标签(分类) /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string Tag1 { get; set; } /// /// 标签(分类) /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string Tag2 { get; set; } - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string Tag3 { get; set; } ///// @@ -71,59 +70,59 @@ namespace dy.net.model.entity /// /// 视频地址(解析会有多个取第一个) /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string VideoUrl { get; set; } /// /// 视频下载后保存路径 /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string VideoSavePath { get; set; } /// /// 视频封面地址 /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string VideoCoverUrl { get; set; } /// /// 视频封面保存路径 /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string VideoCoverSavePath { get; set; } /// /// 作者 /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string Author { get; set; } /// /// 作者ID /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string AuthorId { get; set; } /// /// 作者头像 /// - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string AuthorAvatar { get; set; } - [SugarColumn(Length =2000,IsNullable =true)] + [SugarColumn(Length = 2000, IsNullable = true)] public string AuthorAvatarUrl { get; set; } /// /// 文件hash值唯一值 /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string FileHash { get; set; } /// /// 文件大小(字节) /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public long FileSize { get; set; } /// /// 分辨率(如1920x1080, 3840x2160等) /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string Resolution { get; set; } /// @@ -137,7 +136,7 @@ namespace dy.net.model.entity /// /// 1喜欢的,2收藏的,3关注的 ,4 图片视频 /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public VideoTypeEnum ViedoType { get; set; } /// @@ -146,14 +145,14 @@ namespace dy.net.model.entity public int IsMergeVideo { get; set; } [SugarColumn(IsIgnore = true)] - public string ViedoTypeStr => ViedoType.GetDesc(); + public string ViedoTypeStr => ViedoType.GetDesc(); [SugarColumn(IsIgnore = true)] - public string ViedoCate =>(string.IsNullOrWhiteSpace(Tag1) ? "" : Tag1) + "/" + (string.IsNullOrWhiteSpace(Tag2) ? "" : Tag2); + public string ViedoCate => (string.IsNullOrWhiteSpace(Tag1) ? "" : Tag1) + "/" + (string.IsNullOrWhiteSpace(Tag2) ? "" : Tag2); // 普通字符串字段,显式标记为 SQLite TEXT 类型 - [SugarColumn(ColumnDataType = "TEXT", Length = -1,IsNullable =true)] + [SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)] public string DynamicVideos { get; set; } /// @@ -164,7 +163,7 @@ namespace dy.net.model.entity /// /// 自定义收藏夹、合集、短剧 绑定的Id /// - [SugarColumn(Length =200,IsNullable =true)] + [SugarColumn(Length = 200, IsNullable = true)] public string CateId { get; set; } /// diff --git a/model/entity/DouyinVideoDelete.cs b/model/entity/DouyinVideoDelete.cs index 5ae7a51..e6a3beb 100644 --- a/model/entity/DouyinVideoDelete.cs +++ b/model/entity/DouyinVideoDelete.cs @@ -16,12 +16,12 @@ namespace dy.net.model.entity /// /// 原视频Id /// - [SugarColumn(IsNullable =true,Length =50)] + [SugarColumn(IsNullable = true, Length = 50)] public string ViedoId { get; set; } public DateTime DeleteTime { get; set; } - [SugarColumn(IsNullable =true,Length =1000)] + [SugarColumn(IsNullable = true, Length = 1000)] public string VideoTitle { get; set; } [SugarColumn(IsNullable = true, Length = 1000)] public string VideoSavePath { get; set; } diff --git a/model/response/DouyinSeriesListResponse.cs b/model/response/DouyinSeriesListResponse.cs index 9ec2be2..19e3aaf 100644 --- a/model/response/DouyinSeriesListResponse.cs +++ b/model/response/DouyinSeriesListResponse.cs @@ -220,7 +220,7 @@ namespace dy.net.model.response //[JsonProperty("avatar_larger")] //public DouyinImageResource AvatarLarger { get; set; } - + //[JsonProperty("avatar_schema_list")] //public object AvatarSchemaList { get; set; } // 原始值为null,兼容扩展 @@ -521,7 +521,7 @@ namespace dy.net.model.response //[JsonProperty("new_story_cover")] //public object NewStoryCover { get; set; } // 原始值为null,兼容扩展 - + //[JsonProperty("not_seen_item_id_list")] //public object UnseenItemIds { get; set; } // 原始值为null,兼容扩展 diff --git a/model/response/DouyinVideoInfoResponse.cs b/model/response/DouyinVideoInfoResponse.cs index dd3f73f..b927df6 100644 --- a/model/response/DouyinVideoInfoResponse.cs +++ b/model/response/DouyinVideoInfoResponse.cs @@ -1,5 +1,4 @@ using Newtonsoft.Json; -using System.Collections.Generic; namespace dy.net.model.response { diff --git a/repository/AdminUserRepository.cs b/repository/AdminUserRepository.cs index 8b30dbf..545e5ec 100644 --- a/repository/AdminUserRepository.cs +++ b/repository/AdminUserRepository.cs @@ -38,8 +38,8 @@ namespace dy.net.repository var newpassword = loginUser.Password.Md5(); user.Password = newpassword; user.UserName = loginUser.UserName; - var res = await this.UpdateAsync(user); - return (res?0:-1,res ?"更新成功" : "更新失败"); + var res = await this.UpdateAsync(user); + return (res ? 0 : -1, res ? "更新成功" : "更新失败"); } } else @@ -50,11 +50,11 @@ namespace dy.net.repository } - public async Task GetUser(string userName=null) + public async Task GetUser(string userName = null) { if (string.IsNullOrWhiteSpace(userName)) { - return await this.GetFirstAsync(x=>!string.IsNullOrWhiteSpace(x.Id)); + return await this.GetFirstAsync(x => !string.IsNullOrWhiteSpace(x.Id)); } else { @@ -80,7 +80,7 @@ namespace dy.net.repository { user.Avatar = avatar; var update = await UpdateAsync(user); - return update ; + return update; } } @@ -89,10 +89,10 @@ namespace dy.net.repository /// /// /// - public (int code, string erro) InitUser(AdminUserInfo userInfo) + public (int code, string erro) InitUser(AdminUserInfo userInfo) { - var isInit = this.GetFirst(x=>!string.IsNullOrWhiteSpace(x.Id)); - if (isInit!=null) + var isInit = this.GetFirst(x => !string.IsNullOrWhiteSpace(x.Id)); + if (isInit != null) { return (-1, "系统用户已存在"); } @@ -102,8 +102,8 @@ namespace dy.net.repository userInfo.CreateTime = DateTime.Now; userInfo.Password = Md5Util.Md5(userInfo.Password); - var res = this.Insert(userInfo); - return (res ? 0 : -1, res ? "初始用户成功" : "初始化用户失败"); + var res = this.Insert(userInfo); + return (res ? 0 : -1, res ? "初始用户成功" : "初始化用户失败"); } } } diff --git a/repository/BaseRepository.cs b/repository/BaseRepository.cs index c956c7d..827d59a 100644 --- a/repository/BaseRepository.cs +++ b/repository/BaseRepository.cs @@ -311,7 +311,7 @@ namespace dy.net.repository { return await Db.Queryable().Where(whereExpression).ToListAsync(); } - + /// /// 分页查询 /// diff --git a/repository/DouyinCollectCateRepository.cs b/repository/DouyinCollectCateRepository.cs index a68954b..2af9679 100644 --- a/repository/DouyinCollectCateRepository.cs +++ b/repository/DouyinCollectCateRepository.cs @@ -3,8 +3,6 @@ using dy.net.model.dto; using dy.net.model.entity; using dy.net.utils; using SqlSugar; -using System; -using System.Linq.Expressions; namespace dy.net.repository { @@ -24,7 +22,7 @@ namespace dy.net.repository public async Task<(List list, int totalCount)> GetPagedAsync(DouyinCollectCateRequestDto dto) { var where = this.Db.Queryable() - .Where(x=>x.CateType==dto.cateType) + .Where(x => x.CateType == dto.cateType) .WhereIF(!string.IsNullOrWhiteSpace(dto.cookieId), x => x.CookieId == dto.cookieId); var totalCount = await where.CountAsync(); @@ -174,7 +172,7 @@ namespace dy.net.repository { var videoCounts = await Db.Queryable().Where(x => x.CateId == cate.Id && x.CateXId == cate.XId && x.ViedoType == cate.CateType).CountAsync(); cate.IsEnd = videoCounts == cate.Total; - + var update = await Db.Updateable(cate).UpdateColumns(x => new { x.IsEnd }).ExecuteCommandAsync(); return update > 0; } diff --git a/repository/DouyinCookieRepository.cs b/repository/DouyinCookieRepository.cs index b774680..a43197a 100644 --- a/repository/DouyinCookieRepository.cs +++ b/repository/DouyinCookieRepository.cs @@ -17,7 +17,7 @@ namespace dy.net.repository // 1. 初始化查询:先加固定条件 Status == 1 var query = Db.Queryable() .Where(x => x.Status == 1) - .Where(x=>!string.IsNullOrWhiteSpace(x.Cookies)); // 固定条件(必选) + .Where(x => !string.IsNullOrWhiteSpace(x.Cookies)); // 固定条件(必选) // 2. 若传入自定义条件,叠加 Where(自动 AND 组合) if (whereExpression != null) @@ -38,16 +38,16 @@ namespace dy.net.repository return (list, totalCount); } - public DouyinCookie GetDefault() + public DouyinCookie GetDefault() { - return Db.Queryable() + return Db.Queryable() .First(); } public async Task SwitchAsync(DouyinCookieSwitchDto dto) { - var res =await Db.Updateable().SetColumns(x => new DouyinCookie { Status = dto.Status }).Where(x => x.Id == dto.Id).ExecuteCommandAsync(); + var res = await Db.Updateable().SetColumns(x => new DouyinCookie { Status = dto.Status }).Where(x => x.Id == dto.Id).ExecuteCommandAsync(); return res > 0; } @@ -60,7 +60,7 @@ namespace dy.net.repository return res > 0; } return false; - + } } } diff --git a/repository/DouyinFollowRepository.cs b/repository/DouyinFollowRepository.cs index b062705..08ac5ba 100644 --- a/repository/DouyinFollowRepository.cs +++ b/repository/DouyinFollowRepository.cs @@ -1,5 +1,4 @@ using ClockSnowFlake; -using dy.net.extension; using dy.net.model.dto; using dy.net.model.entity; using dy.net.model.response; @@ -84,7 +83,7 @@ namespace dy.net.repository public async Task> GetSyncFollows(string userId) { return await this.Db.Queryable() - .Where(x => x.OpenSync == true).Where(x => x.mySelfId == userId).Where(x=>!string.IsNullOrWhiteSpace(x.SecUid)) + .Where(x => x.OpenSync == true).Where(x => x.mySelfId == userId).Where(x => !string.IsNullOrWhiteSpace(x.SecUid)) .ToListAsync(); } diff --git a/repository/DouyinVideoRepository.cs b/repository/DouyinVideoRepository.cs index b96346d..bb39df1 100644 --- a/repository/DouyinVideoRepository.cs +++ b/repository/DouyinVideoRepository.cs @@ -1,9 +1,7 @@ using dy.net.extension; using dy.net.model.dto; using dy.net.model.entity; -using Quartz.Util; using SqlSugar; -using System.Linq; namespace dy.net.repository { @@ -15,11 +13,11 @@ namespace dy.net.repository } - + public async Task> GetTopsOrderBySyncTime(int top) { - return await Db.Queryable().Select(x=>new DouyinVideoTopDto {Id=x.Id, Title=x.VideoTitle,Time=x.SyncTime.ToString("yyyy-MM-dd HH:mm:ss")}).Take(top).OrderByDescending(x=>x.Time).ToListAsync(); + return await Db.Queryable().Select(x => new DouyinVideoTopDto { Id = x.Id, Title = x.VideoTitle, Time = x.SyncTime.ToString("yyyy-MM-dd HH:mm:ss") }).Take(top).OrderByDescending(x => x.Time).ToListAsync(); } /// /// @@ -36,16 +34,16 @@ namespace dy.net.repository VideoTypeEnum? enumviedoType = null; - if (!string.IsNullOrEmpty(dto.ViedoType) && dto.ViedoType != "*" && dto.ViedoType != "4") + if (!string.IsNullOrEmpty(dto.ViedoType) && dto.ViedoType != "*" && dto.ViedoType != "4") { enumviedoType = dto.ViedoType.ToVideoTypeEnum(); } - + var where = this.Db.Queryable() //.WhereIF(!string.IsNullOrWhiteSpace(title), x => x.VideoTitle.Contains(title)) .WhereIF(!string.IsNullOrWhiteSpace(dto.Title), x => x.VideoTitle.Contains(dto.Title)) .WhereIF(!string.IsNullOrWhiteSpace(dto.Author), x => x.Author.Contains(dto.Author)) - .WhereIF(!string.IsNullOrWhiteSpace(dto.Tag), x => x.Tag1==dto.Tag) + .WhereIF(!string.IsNullOrWhiteSpace(dto.Tag), x => x.Tag1 == dto.Tag) .WhereIF(start.HasValue, x => x.SyncTime >= start.Value) .WhereIF(end.HasValue, x => x.SyncTime <= end.Value) .WhereIF(start2.HasValue, x => x.CreateTime >= start2.Value) @@ -56,8 +54,8 @@ namespace dy.net.repository var totalCount = await where.CountAsync(); List list = new List(); - if(string.IsNullOrWhiteSpace(dto.SortField)) - list = await where.OrderByDescending(x => x.SyncTime).Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync(); + if (string.IsNullOrWhiteSpace(dto.SortField)) + list = await where.OrderByDescending(x => x.SyncTime).Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync(); else { @@ -100,10 +98,10 @@ namespace dy.net.repository /// /// /// - public (string, string) GetUperLastViedoFileName(string AuthorId, string ViedoNameSimplify) + public (string, string) GetUperLastViedoFileName(string AuthorId, string ViedoNameSimplify) { - var video = this.Db.Queryable().Where(x => x.AuthorId == AuthorId && x.ViedoType == VideoTypeEnum.dy_follows) + var video = this.Db.Queryable().Where(x => x.AuthorId == AuthorId && x.ViedoType == VideoTypeEnum.dy_follows) .Where(x => x.VideoTitleSimplify == ViedoNameSimplify) .OrderByDescending(x => x.CreateTime).First(); @@ -157,7 +155,7 @@ namespace dy.net.repository { if (downs != null) { - return Db.Insertable(downs).ExecuteCommand() > 0; + return Db.Insertable(downs).ExecuteCommand() > 0; } else diff --git a/service/AdminUserService.cs b/service/AdminUserService.cs index e0e12af..fc857f9 100644 --- a/service/AdminUserService.cs +++ b/service/AdminUserService.cs @@ -20,7 +20,7 @@ namespace dy.net.service return await _userRepository.UpdatePwd(loginUser); } - public async Task GetUser(string userName=null) + public async Task GetUser(string userName = null) { return await _userRepository.GetUser(userName); } @@ -30,7 +30,7 @@ namespace dy.net.service return await _userRepository.UpdateAvatar(avatar); } - public (int code, string erro) InitUser(string UserName,string Password) + public (int code, string erro) InitUser(string UserName, string Password) { AdminUserInfo userInfo = new AdminUserInfo { @@ -38,7 +38,7 @@ namespace dy.net.service Password = Password, CreateTime = DateTime.Now }; - return _userRepository.InitUser(userInfo); + return _userRepository.InitUser(userInfo); } } } diff --git a/service/DouyinCollectCateService.cs b/service/DouyinCollectCateService.cs index 2735f17..ab6cd70 100644 --- a/service/DouyinCollectCateService.cs +++ b/service/DouyinCollectCateService.cs @@ -1,10 +1,6 @@ -using ClockSnowFlake; -using dy.net.model.dto; +using dy.net.model.dto; using dy.net.model.entity; -using dy.net.model.response; using dy.net.repository; -using SqlSugar; -using System.Linq.Expressions; namespace dy.net.service { @@ -26,7 +22,7 @@ namespace dy.net.service } - + /// /// @@ -45,7 +41,7 @@ namespace dy.net.service /// /// /// - public async Task<(int add, int update,int delete, bool succ)> Sync(List cates, string ckId,VideoTypeEnum cateType) + public async Task<(int add, int update, int delete, bool succ)> Sync(List cates, string ckId, VideoTypeEnum cateType) { return await _douyinCollectCateRepository.Sync(cates, ckId, cateType); } diff --git a/service/DouyinCommonService.cs b/service/DouyinCommonService.cs index 9e756db..933f084 100644 --- a/service/DouyinCommonService.cs +++ b/service/DouyinCommonService.cs @@ -1,10 +1,6 @@ using ClockSnowFlake; -using dy.net.model.dto; using dy.net.model.entity; -using dy.net.utils; using SqlSugar; -using System.Reflection; -using System.Threading.Tasks; //using static Org.BouncyCastle.Math.EC.ECCurve; namespace dy.net.service @@ -157,7 +153,7 @@ namespace dy.net.service .ToListAsync(); } - + #region 测试创建数据库 diff --git a/service/DouyinCookieService.cs b/service/DouyinCookieService.cs index 899f195..12269a0 100644 --- a/service/DouyinCookieService.cs +++ b/service/DouyinCookieService.cs @@ -2,9 +2,7 @@ using dy.net.model.dto; using dy.net.model.entity; using dy.net.repository; -using SqlSugar; using System.Linq.Expressions; -using System.Threading.Tasks; namespace dy.net.service { @@ -33,7 +31,7 @@ namespace dy.net.service /// public async Task IsInit() { - return await _cookieRepository.ExistsAsync(x => !string.IsNullOrEmpty(x.Id)); + return await _cookieRepository.ExistsAsync(x => !string.IsNullOrEmpty(x.Id)); } public async Task Add(DouyinCookie dyUserCookies) { @@ -52,7 +50,7 @@ namespace dy.net.service } var cookie = new DouyinCookie { - UserName = "douyin2026", + UserName = "douyin2026", Cookies = "", SecUserId = "", Id = IdGener.GetLong().ToString(), @@ -64,11 +62,11 @@ namespace dy.net.service //CollHasSyncd = 0, //FavHasSyncd = 0, //UperSyncd = 0, - MyUserId="" + MyUserId = "" }; - return _cookieRepository.Insert(cookie); + return _cookieRepository.Insert(cookie); } - + // 查询单个 public async Task GetByIdAsync(string id) { diff --git a/service/DouyinFollowService.cs b/service/DouyinFollowService.cs index 74e62dc..7766deb 100644 --- a/service/DouyinFollowService.cs +++ b/service/DouyinFollowService.cs @@ -4,7 +4,6 @@ using dy.net.model.entity; using dy.net.model.response; using dy.net.repository; using SqlSugar; -using System.Linq.Expressions; namespace dy.net.service { @@ -32,8 +31,8 @@ namespace dy.net.service /// public async Task AddAsync(DouyinFollowed followed) { - var foll= await _followRepository.GetFirstAsync(x=>x.SecUid==followed.SecUid && x.mySelfId== followed.mySelfId); - if(foll!=null) + var foll = await _followRepository.GetFirstAsync(x => x.SecUid == followed.SecUid && x.mySelfId == followed.mySelfId); + if (foll != null) { return false; } @@ -59,7 +58,7 @@ namespace dy.net.service /// public async Task> GetHandFollows() { - return await _followRepository.GetListAsync(x=>x.IsNoFollowed); + return await _followRepository.GetListAsync(x => x.IsNoFollowed); } /// /// 导入非关注 @@ -114,8 +113,8 @@ namespace dy.net.service return await _followRepository.Sync(followInfos, ck); } - public async Task GetByUperId(string uperId,string myUid) - { + public async Task GetByUperId(string uperId, string myUid) + { return await _followRepository.GetBySecUId(uperId, myUid); } @@ -143,7 +142,7 @@ namespace dy.net.service { return await _followRepository.DeleteByIdAsync(dto.Id); } - + /// /// 打开或关闭同步 diff --git a/service/DouyinHttpClientService.cs b/service/DouyinHttpClientService.cs index 81e12d6..0369a8b 100644 --- a/service/DouyinHttpClientService.cs +++ b/service/DouyinHttpClientService.cs @@ -1,13 +1,10 @@ -using Dm; -using dy.net.model.dto; +using dy.net.model.dto; using dy.net.model.entity; using dy.net.model.response; using dy.net.utils; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; -using System.Net.Http; -using System.Web; namespace dy.net.service { @@ -15,7 +12,7 @@ namespace dy.net.service { - readonly IHttpClientFactory _clientFactory; + private readonly IHttpClientFactory _clientFactory; public DouyinHttpClientService(IHttpClientFactory clientFactory) { _clientFactory = clientFactory; @@ -110,7 +107,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model= JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncCollectVideos fail: {data}"); return model; @@ -169,7 +166,7 @@ namespace dy.net.service } else { - Serilog.Log.Error("SyncCollectFolderList ,{StatusCode}", respose.StatusCode); + Serilog.Log.Error("SyncCollectFolderList ,{StatusCode}", respose.StatusCode); return null; } } @@ -231,7 +228,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model= JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncCollectVideosByCollectId fail: {data}"); return model; @@ -293,7 +290,7 @@ namespace dy.net.service Serilog.Log.Error($"SyncMixList : {respose.StatusCode}"); return null; } - + } catch (Exception ex) { @@ -352,7 +349,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model = JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncMixViedosByMixId fail: {data}"); return model; @@ -413,7 +410,7 @@ namespace dy.net.service Serilog.Log.Error($"SyncShortList fail: {respose.StatusCode}"); return null; } - + } catch (Exception ex) { @@ -472,7 +469,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model= JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncSeriesViedosByMSeriesId fail: {data}"); return model; @@ -544,7 +541,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model= JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncFavoriteVideos fail: {data}"); return model; @@ -616,7 +613,7 @@ namespace dy.net.service if (respose.IsSuccessStatusCode) { var data = await respose.Content.ReadAsStringAsync(); - var model= JsonConvert.DeserializeObject(data); + var model = JsonConvert.DeserializeObject(data); if (model == null) Serilog.Log.Error($"SyncUpderPostVideos fail: {data}"); return model; diff --git a/service/DouyinMergeVideoService.cs b/service/DouyinMergeVideoService.cs index a28b21c..42fc3e1 100644 --- a/service/DouyinMergeVideoService.cs +++ b/service/DouyinMergeVideoService.cs @@ -1,9 +1,7 @@ -using ClockSnowFlake; -using dy.net.extension; +using dy.net.extension; using dy.net.model.dto; using dy.net.utils; using Serilog; -using System.Collections.Generic; using System.Security.Cryptography; namespace dy.net.service @@ -37,7 +35,7 @@ namespace dy.net.service /// /// /// - public async Task<(string mp4Path,string mp3Path)> MergeMultipleVideosAsync( + public async Task<(string mp4Path, string mp3Path)> MergeMultipleVideosAsync( List videoFilePaths, string audioPath, string savePath, @@ -51,11 +49,11 @@ namespace dy.net.service if (SuccessPaths != null && SuccessPaths.Length > 0) { mergMusicPath = SuccessPaths[0]; - mp3Path= SuccessPaths[0]; + mp3Path = SuccessPaths[0]; } } var ffmpeg = new FFmpegHelper(); - var mp4Path= await ffmpeg.MergeMultipleVideosAsync(videoFilePaths, mergMusicPath, savePath); + var mp4Path = await ffmpeg.MergeMultipleVideosAsync(videoFilePaths, mergMusicPath, savePath); return (mp4Path, mp3Path); } @@ -78,7 +76,7 @@ namespace dy.net.service Path.GetFileNameWithoutExtension(filePath) != "silent_10") .ToList(); - if (customMusics != null && customMusics.Any()) + if (customMusics != null && customMusics.Any()) { if (customMusics.Count() == 1) return customMusics.FirstOrDefault(); @@ -136,12 +134,12 @@ namespace dy.net.service // 保存下载的图片(如果需要) if (downImage) { - await SaveDownloadedFilesAsync(rawImages, fileNamefolder, "jpg",Path.GetFileNameWithoutExtension(outputVideoPath)); + await SaveDownloadedFilesAsync(rawImages, fileNamefolder, "jpg", Path.GetFileNameWithoutExtension(outputVideoPath)); } // 2. 下载音频 string[] rawAudios = Array.Empty(); - if (mergeImg2Viedo && request.AudioUrls != null && request.AudioUrls.Count > 0) + if (mergeImg2Viedo && request.AudioUrls != null && request.AudioUrls.Count > 0) { var (audios, audioError) = await DownloadMediaAsync( request.AudioUrls, Path.Combine(tempDir, "raw-audios"), "audio_", "mp3", cookie); @@ -154,7 +152,7 @@ namespace dy.net.service // 保存下载的音频(如果需要) if (downMp3) { - var ext= Path.GetExtension(rawAudios[0]); + var ext = Path.GetExtension(rawAudios[0]); await SaveDownloadedFilesAsync(rawAudios, fileNamefolder, ext, Path.GetFileNameWithoutExtension(outputVideoPath)); } } @@ -162,7 +160,7 @@ namespace dy.net.service // 不合成视频,直接返回成功 if (!mergeImg2Viedo) { - Log.Debug($"根据系统配置设置不下载图文视频-[{outputVideoPath}],{(downImage?"下载图片":"不下载图片")},{(downMp3?"下载音频":"不下载音频")}"); + Log.Debug($"根据系统配置设置不下载图文视频-[{outputVideoPath}],{(downImage ? "下载图片" : "不下载图片")},{(downMp3 ? "下载音频" : "不下载音频")}"); return true; } @@ -237,7 +235,7 @@ namespace dy.net.service /// /// 保存下载的文件(图片/音频)到目标目录 /// - private static async Task SaveDownloadedFilesAsync(string[] sourcePaths, string targetFolder, string defaultExt,string videoFileName) + private static async Task SaveDownloadedFilesAsync(string[] sourcePaths, string targetFolder, string defaultExt, string videoFileName) { if (sourcePaths == null || sourcePaths.Length == 0) return; Directory.CreateDirectory(targetFolder); // 确保目标目录存在 @@ -329,7 +327,7 @@ namespace dy.net.service /// 通用媒体下载方法 private async Task<(string[] SuccessPaths, string ErrorMsg)> DownloadMediaAsync( - List urls, string saveDir, string prefix, string ext,string cookie) + List urls, string saveDir, string prefix, string ext, string cookie) { var successPaths = new List(); for (var i = 0; i < urls.Count; i++) @@ -341,8 +339,8 @@ namespace dy.net.service try { - var (Success, ActualSavePath) = await douyinHttpClientService.DownloadAsync(url, savePath, cookie); - if(Success) + var (Success, ActualSavePath) = await douyinHttpClientService.DownloadAsync(url, savePath, cookie); + if (Success) { successPaths.Add(ActualSavePath); } @@ -350,7 +348,7 @@ namespace dy.net.service { Serilog.Log.Error($"下载失败:{url} → {savePath}"); } - //Console.WriteLine($"下载成功:{url} → {savePath}"); + //Console.WriteLine($"下载成功:{url} → {savePath}"); } catch (Exception ex) { diff --git a/service/DouyinQuartzJobService.cs b/service/DouyinQuartzJobService.cs index 7b6fb10..a9b75f5 100644 --- a/service/DouyinQuartzJobService.cs +++ b/service/DouyinQuartzJobService.cs @@ -3,10 +3,6 @@ using dy.net.model.dto; using dy.net.utils; using Quartz; using Serilog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace dy.net.service { @@ -76,8 +72,8 @@ namespace dy.net.service VideoTypeEnum.dy_series.GetDesc(), new JobConfig( typeof(DouyinSeriesSyncJob), - "dy.job.key.series", - "dy.trigger.key.series", + "dy.job.key.series", + "dy.trigger.key.series", "抖音收藏夹短剧同步任务") }, { @@ -99,7 +95,6 @@ namespace dy.net.service /// 启动所有抖音相关定时任务(所有任务独立执行) /// /// Cron表达式或间隔分钟数(所有任务使用相同的执行频率) - /// /// 是否启动成功 public async Task InitOrReStartAllJobs(string expression) { @@ -120,6 +115,8 @@ namespace dy.net.service // 执行任务启动逻辑 foreach (var jobKey in JobConfigs.Keys) { + if (jobKey == "follow_user_once") + continue; if (jobKey == "follow_user") expression = "60"; var startSuccess = await StartJobAsync(jobKey, expression); if (startSuccess) @@ -131,7 +128,7 @@ namespace dy.net.service Log.Error($"启动任务失败:{jobKey}"); } } - Log.Information($"共启动 {JobConfigs.Count} 个定时任务"); + Log.Information($"共启动 {JobConfigs.Count - 1} 个定时任务"); //await StartJobAsync(VideoTypeEnum.dy_custom_collect.GetDesc(), expression); diff --git a/service/DouyinQuartzJobServiceXXX.cs b/service/DouyinQuartzJobServiceXXX.cs deleted file mode 100644 index 87d3816..0000000 --- a/service/DouyinQuartzJobServiceXXX.cs +++ /dev/null @@ -1,371 +0,0 @@ -//using dy.net.job; -//using dy.net.model.dto; -//using Quartz; -//using Quartz.Impl.Matchers; -//using Serilog; -//using System; -//using System.Threading.Tasks; - -//namespace dy.net.service -//{ -// /// -// /// 抖音相关定时任务服务 -// /// -// public class DouyinQuartzJobService -// { -// private readonly ISchedulerFactory _schedulerFactory; -// private const string DefaultJobGroup = "dysync.net"; -// private const int DefaultIntervalMinutes = 30; -// private const int DefaultCronStartDelaySeconds = 30; -// private const int DefaultSimpleStartDelaySeconds = 3; - -// // 任务顺序依赖配置(核心:定义执行顺序,供 Listener 使用) -// public Dictionary JobDependency { get; } = new() -// { -// {"collect", "favorite"}, // collect 执行完 → 触发 favorite -// {"favorite", "followed"}, // favorite 执行完 → 触发 followed -// {"followed", null}, // followed 执行完 → 一轮任务结束 -// }; - -// // 任务配置信息(保持原有配置不变,改为 public 供 Listener 访问) -// public Dictionary JobConfigs { get; } = new() -// { -// { -// "collect", -// new JobConfig( -// typeof(DouyinCollectSyncJob), -// "dy.job.key.collect", -// "dy.trigger.key.collect", -// "抖音收藏同步任务") -// }, -// { -// "favorite", -// new JobConfig( -// typeof(DouyinFavoritSyncJob), -// "dy.job.key.favorite", -// "dy.trigger.key.favorite", -// "抖音点赞同步任务") -// }, -// { -// "followed", -// new JobConfig( -// typeof(DouyinFollowedSyncJob), -// "dy.job.key.followed", -// "dy.trigger.key.followed", -// "抖音关注博主作品同步任务") -// }, -// { -// "follow_user", -// new JobConfig( -// typeof(DouyinFollowsAndCollnectsSyncJob), -// "dy.job.key.follow_user", -// "dy.trigger.key.follow_user", -// "抖音关注列表同步任务") -// }, - -// { -// "custom_collect", -// new JobConfig( -// typeof(DouyinCollectCustomSyncJob), -// "dy.job.key.custom_collect", -// "dy.trigger.key.custom_collect", -// "抖音自定义收藏夹列表同步任务") -// }, - -// { -// "mix", -// new JobConfig( -// typeof(DouyinMixSyncJob), -// "dy.job.key.mix", -// "dy.trigger.key.mix", -// "抖音收藏夹合集同步任务") -// }, -// { -// "series", -// new JobConfig( -// typeof(DouyinSeriesSyncJob), -// "dy.job.key.mix", -// "dy.trigger.key.mix", -// "抖音收藏夹短剧同步任务") -// }, -// { -// "follow_user_once", -// new JobConfig( -// typeof(DouyinFollowsAndCollnectsSyncJob), -// "dy.job.key.follow_user_once", -// "dy.trigger.key.follow_user_once", -// "抖音关注同步任务(单次执行)") -// } -// }; - -// public DouyinQuartzJobService(ISchedulerFactory schedulerFactory) -// { -// _schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory)); -// } - -// /// -// /// 启动所有抖音相关定时任务(顺序执行模式) -// /// -// /// Cron表达式或间隔分钟数(控制整个链条的执行频率) -// /// 是否启动成功 -// public async Task InitOrReStartAllJobs(string expression) -// { -// if (string.IsNullOrWhiteSpace(expression)) -// { -// Log.Debug("定时任务表达式为空,使用默认配置({DefaultMinutes}分钟)", DefaultIntervalMinutes); -// expression = DefaultIntervalMinutes.ToString(); -// } - -// try -// { -// var scheduler = await _schedulerFactory.GetScheduler(); - -// // 1. 注册独立的 JobListener(核心:注入配置和服务) -// await RegisterJobListener(scheduler); - -// // 2. 移除所有已存在的任务(避免重复调度) -// await RemoveAllExistingJobs(scheduler); - -// // 3. 只启动第一个任务(collect),后续任务由 Listener 自动触发 -// var firstJobConfigKey = "collect"; -// //var startSuccess = await StartJobAsync(firstJobConfigKey, expression); - -// //if (startSuccess) -// //{ -// // Log.Debug($"同步任务执行顺序:collect → favorite → followed-->默认每{expression}分钟执行一次..."); -// //} -// //else -// //{ -// // Log.Error($"任务执行失败(任务 {firstJobConfigKey} 启动失败)"); -// //} -// //启动follow_user--这个与其他几个任务没有依赖关系,所以单独启动 -// //await StartJobAsync("collect", expression); -// //await StartJobAsync("follow_user", expression); -// //await StartJobAsync("follow_user", expression); -// //await StartJobAsync("follow_user", expression); -// //await StartJobAsync("custom_collect", expression); -// //await StartJobAsync("mix", expression); -// //await StartJobAsync("series", expression); -// return true; -// } -// catch (Exception ex) -// { -// Log.Error(ex, "【任务服务】初始化任务链条异常"); -// return false; -// } -// } - -// /// -// /// 启动关注同步任务(单次执行) -// /// -// public async Task StartFollowJobOnceAsync() -// { -// return await StartOneTimeJobAsync("follow_user_once"); -// } - -// /// -// /// 注册独立的 JobListener(核心步骤) -// /// -// private async Task RegisterJobListener(IScheduler scheduler) -// { -// // 创建独立的 Listener 实例,注入依赖(任务配置、依赖关系、当前服务) -// var dependencyListener = new DouyinJobDependencyListener( -// JobConfigs, // 任务配置 -// JobDependency, // 依赖顺序 -// this // 任务服务(用于触发下一个任务) -// ); - -// // 注册 Listener:仅监听 DefaultJobGroup 分组的任务(精准匹配,避免影响其他任务) -// scheduler.ListenerManager.AddJobListener( -// dependencyListener, -// GroupMatcher.GroupEquals(DefaultJobGroup) -// ); - -// Log.Information("【任务服务】JobListener 注册成功:{ListenerName}", dependencyListener.Name); -// } - -// /// -// /// 移除所有已存在的任务(避免重复调度) -// /// -// private async Task RemoveAllExistingJobs(IScheduler scheduler) -// { -// var jobKeys = JobConfigs.Values.Select(config => new JobKey(config.JobKey, DefaultJobGroup)).ToList(); -// foreach (var jobKey in jobKeys) -// { -// if (await scheduler.CheckExists(jobKey)) -// { -// Log.Information("【任务服务】移除已存在的任务: {JobKey}", jobKey); -// await scheduler.DeleteJob(jobKey); -// } -// } -// } - -// /// -// /// 启动指定定时任务(public 修饰,供 Listener 调用) -// /// -// /// 任务配置Key(如:collect、favorite) -// /// 定时表达式(依赖触发时传空) -// /// 是否为依赖触发(true=立即执行,false=定时执行) -// /// 是否启动成功 -// public async Task StartJobAsync(string configKey, string expression, bool isDependencyTrigger = false) -// { -// if (!JobConfigs.TryGetValue(configKey, out var jobConfig)) -// { -// Log.Error("【任务服务】找不到任务配置: {ConfigKey}", configKey); -// return false; -// } - -// try -// { -// var scheduler = await _schedulerFactory.GetScheduler(); -// var jobKey = new JobKey(jobConfig.JobKey, DefaultJobGroup); -// // 触发器Key:区分「定时触发」和「依赖触发」,避免冲突 -// var triggerKey = new TriggerKey( -// $"{jobConfig.TriggerKey}_{(isDependencyTrigger ? "dependency" : "main")}", -// DefaultJobGroup -// ); - -// // 移除已存在的任务(防止重复执行) -// await RemoveExistingJobAsync(scheduler, jobKey); - -// // 创建任务详情(添加禁止并发执行特性,避免顺序混乱) -// var jobDetail = JobBuilder.Create(jobConfig.JobType) -// .WithIdentity(jobKey) -// .WithDescription(jobConfig.Description) -// .DisallowConcurrentExecution() // 关键:禁止同一任务并发执行 -// .Build(); - -// // 创建立触发器 -// ITrigger trigger = isDependencyTrigger -// ? CreateDependencyTrigger(triggerKey, jobConfig.Description) // 依赖触发:立即执行 -// : CreateScheduledTrigger(triggerKey, expression, jobConfig.Description); // 定时触发:按表达式执行 - -// // 调度任务 -// await scheduler.ScheduleJob(jobDetail, trigger); -// Log.Information("【任务服务】启动任务成功 - 任务描述: {JobDescription}, 触发类型: {TriggerType}, 表达式: {Expression}", -// jobConfig.Description, -// isDependencyTrigger ? "依赖触发(立即执行)" : "定时触发", -// isDependencyTrigger ? "无" : expression); - -// return true; -// } -// catch (Exception ex) -// { -// Log.Error(ex, "【任务服务】启动任务失败 - 任务描述: {JobDescription}", jobConfig.Description); -// return false; -// } -// } - -// /// -// /// 启动单次执行任务(保持原有逻辑不变) -// /// -// private async Task StartOneTimeJobAsync(string configKey) -// { -// if (!JobConfigs.TryGetValue(configKey, out var jobConfig)) -// { -// Log.Error("【任务服务】找不到任务配置: {ConfigKey}", configKey); -// return false; -// } - -// try -// { -// var scheduler = await _schedulerFactory.GetScheduler(); -// var jobKey = new JobKey(jobConfig.JobKey, DefaultJobGroup); -// var triggerKey = new TriggerKey(jobConfig.TriggerKey, DefaultJobGroup); - -// await RemoveExistingJobAsync(scheduler, jobKey); - -// var jobDetail = JobBuilder.Create(jobConfig.JobType) -// .WithIdentity(jobKey) -// .WithDescription(jobConfig.Description) -// .DisallowConcurrentExecution() -// .Build(); - -// var trigger = TriggerBuilder.Create() -// .WithIdentity(triggerKey) -// .WithDescription($"{jobConfig.Description} - 单次执行") -// .StartNow() -// .Build(); - -// await scheduler.ScheduleJob(jobDetail, trigger); -// Log.Information("【任务服务】启动单次任务成功 - 任务描述: {JobDescription}", jobConfig.Description); - -// return true; -// } -// catch (Exception ex) -// { -// Log.Error(ex, "【任务服务】启动单次任务失败 - 任务描述: {JobDescription}", jobConfig.Description); -// return false; -// } -// } - -// /// -// /// 创建「定时触发器」(按表达式执行,仅第一个任务使用) -// /// -// private ITrigger CreateScheduledTrigger(TriggerKey triggerKey, string expression, string jobDescription) -// { -// // Cron表达式格式 -// if (CronExpression.IsValidExpression(expression)) -// { -// return TriggerBuilder.Create() -// .WithIdentity(triggerKey) -// .WithDescription($"{jobDescription} - Cron调度") -// .WithCronSchedule(expression) -// .StartAt(DateTime.Now.AddSeconds(DefaultCronStartDelaySeconds)) -// .Build(); -// } - -// // 数字间隔格式(分钟) -// if (int.TryParse(expression, out int intervalMinutes)) -// { -// intervalMinutes = Math.Max(1, intervalMinutes); // 最小间隔1分钟 -// return TriggerBuilder.Create() -// .WithIdentity(triggerKey) -// .WithDescription($"{jobDescription} - 间隔{intervalMinutes}分钟调度") -// .StartAt(DateTime.Now.AddSeconds(DefaultSimpleStartDelaySeconds)) -// .WithSimpleSchedule(x => x -// .WithIntervalInMinutes(intervalMinutes) -// .RepeatForever()) -// .Build(); -// } - -// // 无效表达式,使用默认配置 -// Log.Warning("【任务服务】无效的任务表达式: {Expression},使用默认间隔{DefaultMinutes}分钟", -// expression, DefaultIntervalMinutes); - -// return TriggerBuilder.Create() -// .WithIdentity(triggerKey) -// .WithDescription($"{jobDescription} - 默认间隔调度") -// .StartAt(DateTime.Now.AddSeconds(DefaultSimpleStartDelaySeconds)) -// .WithSimpleSchedule(x => x -// .WithIntervalInMinutes(DefaultIntervalMinutes) -// .RepeatForever()) -// .Build(); -// } - -// /// -// /// 创建「依赖触发器」(立即执行,仅执行一次) -// /// -// private ITrigger CreateDependencyTrigger(TriggerKey triggerKey, string jobDescription) -// { -// return TriggerBuilder.Create() -// .WithIdentity(triggerKey) -// .WithDescription($"{jobDescription} - 依赖触发(立即执行)") -// .StartNow() // 立即触发 -// .Build(); -// } - -// /// -// /// 移除已存在的任务(保持原有逻辑不变) -// /// -// private async Task RemoveExistingJobAsync(IScheduler scheduler, JobKey jobKey) -// { -// if (await scheduler.CheckExists(jobKey)) -// { -// Log.Information("【任务服务】移除已存在的任务: {JobKey}", jobKey); -// await scheduler.DeleteJob(jobKey); -// } -// } - -//} -//} \ No newline at end of file diff --git a/service/DouyinVideoService.cs b/service/DouyinVideoService.cs index 2acaf4f..65d1699 100644 --- a/service/DouyinVideoService.cs +++ b/service/DouyinVideoService.cs @@ -3,13 +3,8 @@ using dy.net.model.dto; using dy.net.model.entity; using dy.net.repository; using dy.net.utils; -using Newtonsoft.Json; using Serilog; using SqlSugar; -using System.Collections.Generic; -using System.ComponentModel; -using System.Text.RegularExpressions; -using System.Threading.Tasks; namespace dy.net.service { @@ -382,7 +377,7 @@ namespace dy.net.service /// /// /// - public async Task> GetChartData(int day=7) + public async Task> GetChartData(int day = 7) { var date = DateTime.Now.AddDays(-day); @@ -517,7 +512,7 @@ namespace dy.net.service public async Task HandOldFolderVideos() { // 1. 查询目标数据 - var list = await _dyCollectVideoRepository.GetListAsync(x=>x.ViedoType == VideoTypeEnum.dy_favorite || x.ViedoType == VideoTypeEnum.dy_collects ); + var list = await _dyCollectVideoRepository.GetListAsync(x => x.ViedoType == VideoTypeEnum.dy_favorite || x.ViedoType == VideoTypeEnum.dy_collects); // 缓存已处理的「Tag1+下一级文件夹」组合(避免重复移动) var processedFolderPairs = new HashSet(StringComparer.OrdinalIgnoreCase); diff --git a/utils/DouyinFileNameHelper.cs b/utils/DouyinFileNameHelper.cs index 3623621..618c059 100644 --- a/utils/DouyinFileNameHelper.cs +++ b/utils/DouyinFileNameHelper.cs @@ -1,6 +1,4 @@ -using ClockSnowFlake; -using System.IO; -using System.Text; +using System.Text; using System.Text.RegularExpressions; namespace dy.net.utils @@ -22,7 +20,7 @@ namespace dy.net.utils string result = string.Empty; // 1. 空值处理:直接返回默认名 if (string.IsNullOrWhiteSpace(originalName)) - result= defaultName.Replace(" ",""); + result = defaultName.Replace(" ", ""); else { // 2. 过滤 Linux 非法字符: @@ -44,7 +42,7 @@ namespace dy.net.utils // 3. 计算 UTF-8 字节数,若未超 255 字节,直接返回 byte[] utf8Bytes = Encoding.UTF8.GetBytes(sanitizedName); if (utf8Bytes.Length <= 100) - result= sanitizedName.Replace(" ", ""); + result = sanitizedName.Replace(" ", ""); else { // 4. 超过 255 字节,截取前 255 字节(避免破坏 UTF-8 字符) @@ -55,14 +53,14 @@ namespace dy.net.utils string truncatedName = Encoding.UTF8.GetString(truncatedBytes).TrimEnd('\0').Replace(" ", ""); // 移除可能的空字符 // 6. 极端情况:截取后为空(如全是非法字符替换后无有效内容),返回默认名 - result= string.IsNullOrWhiteSpace(truncatedName) ? defaultName : truncatedName; + result = string.IsNullOrWhiteSpace(truncatedName) ? defaultName : truncatedName; } if (isfolder) { result = KeepChineseLettersAndNumbers(result); } } - return result; + return result; } diff --git a/utils/DouyinRequestParamManager.cs b/utils/DouyinRequestParamManager.cs index 1562f46..19c6186 100644 --- a/utils/DouyinRequestParamManager.cs +++ b/utils/DouyinRequestParamManager.cs @@ -1,5 +1,4 @@ using dy.net.model.dto; -using System.Collections.Generic; namespace dy.net.utils { diff --git a/utils/FFmpegHelper.cs b/utils/FFmpegHelper.cs index dd67b9c..654db2d 100644 --- a/utils/FFmpegHelper.cs +++ b/utils/FFmpegHelper.cs @@ -1,14 +1,8 @@ using dy.net.model.dto; using Serilog; -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; -using System.IO; -using System.Linq; using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace dy.net.utils { diff --git a/utils/LogFileCleaner.cs b/utils/LogFileCleaner.cs index d3f2507..deb0890 100644 --- a/utils/LogFileCleaner.cs +++ b/utils/LogFileCleaner.cs @@ -7,7 +7,7 @@ /// /// 日志文件所在目录 /// 清除N天之前的日志文件 - public static void CleanOldLogFiles(string logDirectory,int n) + public static void CleanOldLogFiles(string logDirectory, int n) { // 计算n天前的时间点 DateTime threeDaysAgo = DateTime.Now.AddDays(-n); diff --git a/utils/NfoFileGenerator.cs b/utils/NfoFileGenerator.cs index 6ca2b53..de4d8de 100644 --- a/utils/NfoFileGenerator.cs +++ b/utils/NfoFileGenerator.cs @@ -1,6 +1,5 @@ using dy.net.model.dto; using dy.net.model.entity; -using System.IO; using System.Text; using System.Xml.Linq; @@ -19,7 +18,7 @@ namespace dy.net.utils /// /// 视频信息 /// 一个表示异步操作的任务 - public static void GenerateVideoNfoFile(DouyinVideo video) + public static void GenerateVideoNfoFile(DouyinVideo video) { try { @@ -39,7 +38,7 @@ namespace dy.net.utils { var fileExt = Path.GetExtension(video.AuthorAvatar); var actorsDir = Path.Combine(videoDirectory, ".actors"); - if(!Directory.Exists(actorsDir)) + if (!Directory.Exists(actorsDir)) { Directory.CreateDirectory(actorsDir); } @@ -55,7 +54,7 @@ namespace dy.net.utils } - var nfoInfo= new DouyinVideoNfo + var nfoInfo = new DouyinVideoNfo { Actors = new List { @@ -82,7 +81,7 @@ namespace dy.net.utils { GenerateNfoFile(nfoInfo, nfoFullPath); } - + } catch (Exception ex) { @@ -90,7 +89,7 @@ namespace dy.net.utils } } - private static void GenerateNfoFile(DouyinVideoNfo videoInfo, string filePath,string xmlRoot= "movie") + private static void GenerateNfoFile(DouyinVideoNfo videoInfo, string filePath, string xmlRoot = "movie") { try { @@ -143,7 +142,7 @@ namespace dy.net.utils if (!string.IsNullOrWhiteSpace(actor.Role)) actorElement.Add(new XElement("role", CleanInvalidXmlChars(actor.Role))); - actorElement.Add(new XElement("tmdbid", "")); + actorElement.Add(new XElement("tmdbid", "")); root.Add(actorElement); } diff --git a/utils/VideoTitleGenerator.cs b/utils/VideoTitleGenerator.cs index 2aa757a..22a3e0b 100644 --- a/utils/VideoTitleGenerator.cs +++ b/utils/VideoTitleGenerator.cs @@ -55,7 +55,7 @@ namespace dy.net.utils return placeholderMap.TryGetValue(placeholderKey, out var value) ? value : match.Value; }); - var fullName= finalTitle.Replace("--","-"); + var fullName = finalTitle.Replace("--", "-"); if (fullName.Length > 60) {