This commit is contained in:
jianzhichu
2025-12-20 12:19:49 +08:00
parent 0549688e6f
commit 7666ab109d
13 changed files with 462 additions and 203 deletions
+10 -10
View File
@@ -35,7 +35,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> UpdatePwd(UpdatePwdRequest user) public async Task<IActionResult> UpdatePwd(UpdatePwdRequest user)
{ {
var (code, erro) = await _userService.UpdatePwd(user); var (code, erro) = await _userService.UpdatePwd(user);
return Ok(new { code, erro }); return ApiResult.Success("", erro);
} }
@@ -47,7 +47,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> GetUserAvatar() public async Task<IActionResult> GetUserAvatar()
{ {
var user = await _userService.GetUser(); var user = await _userService.GetUser();
return Ok(new { code = 0, error = "", data = new { user?.Avatar, user?.Id, user?.UserName } }); return ApiResult.Success(new { user?.Avatar, user?.Id, user?.UserName });
} }
/// <summary> /// <summary>
@@ -64,7 +64,7 @@ namespace dy.net.Controllers
long maxFileSize = 5 * 1024 * 1024; // 限制文件大小为5MB long maxFileSize = 5 * 1024 * 1024; // 限制文件大小为5MB
if (file.Length > maxFileSize) if (file.Length > maxFileSize)
{ {
return Ok(new { code = -1, erro = "文件最大只能上传5M" }); return ApiResult.Fail("文件最大只能上传5M");
} }
var fileName = $"{IdGener.GetGuid()}_{file.FileName}"; var fileName = $"{IdGener.GetGuid()}_{file.FileName}";
var filePath = webHostEnvironment.IsProduction() ? var filePath = webHostEnvironment.IsProduction() ?
@@ -86,15 +86,16 @@ namespace dy.net.Controllers
catch (Exception ex) catch (Exception ex)
{ {
Serilog.Log.Error($"delete file error ,{ex.Message}"); Serilog.Log.Error($"delete file error ,{ex.Message}");
return ApiResult.Fail(ex.Message);
} }
var update = await _userService.UpdateAvatar(fileName); var update = await _userService.UpdateAvatar(fileName);
return Ok(new { code = update ? 0 : -1, erro = update ? "" : "上传失败", data = update ? fileName : "" }); return ApiResult.SuccOrFail(update , update ? fileName : "", update ? "" : "上传失败");
} }
} }
else else
{ {
return Ok(new { code = -1, erro = "空文件" }); return ApiResult.Fail("无效的文件");
} }
} }
@@ -110,7 +111,7 @@ namespace dy.net.Controllers
{ {
if (loginUserInfo == null) if (loginUserInfo == null)
{ {
return Ok(new { code = -1, erro = "参数不能为空" }); return ApiResult.Fail("参数不能为空");
} }
else else
{ {
@@ -118,7 +119,7 @@ namespace dy.net.Controllers
if (user == null) if (user == null)
{ {
return Ok(new { code = -1, erro = "用户名或密码不正确" }); return ApiResult.Fail("用户名或密码不正确");
} }
else else
{ {
@@ -126,12 +127,11 @@ namespace dy.net.Controllers
{ {
var tokenString = GenerateJwtToken(user.UserName); var tokenString = GenerateJwtToken(user.UserName);
return Ok(new { code = 0, erro = "", token = tokenString, expires = 24 * 60 * 60 * 1000, data = user.UserName });
return Ok(new { code = 0, erro = "", token = tokenString, expires = 24 * 60 * 60 * 1000,data=user.UserName });
} }
else else
{ {
return Ok(new { code = -1, erro = "用户名或密码不正确" }); return ApiResult.Fail("用户名或密码不正确");
} }
} }
} }
+25 -32
View File
@@ -53,7 +53,7 @@ namespace dy.net.Controllers
cookies = await douyinCookieService.GetAllAsync() cookies = await douyinCookieService.GetAllAsync()
}; };
return Ok(new { code = 0, data = dto }); return ApiResult.Success(dto);
} }
@@ -67,7 +67,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> ImportConf(AppConfigImportDto dto) public async Task<IActionResult> ImportConf(AppConfigImportDto dto)
{ {
if (dto == null) if (dto == null)
return BadRequest("json数据为空"); return ApiResult.Fail("json数据为空");
var follows = dto.follows; var follows = dto.follows;
if (follows != null && follows.Count > 0) if (follows != null && follows.Count > 0)
@@ -88,16 +88,14 @@ namespace dy.net.Controllers
if (cookies != null && cookies.Count > 0) if (cookies != null && cookies.Count > 0)
{ {
var importCookies=await douyinCookieService.ImportCookies(cookies); var importCookies = await douyinCookieService.ImportCookies(cookies);
if (importCookies) if (importCookies)
{ {
Serilog.Log.Debug("抖音Cookie配置导入成功"); Serilog.Log.Debug("抖音Cookie配置导入成功");
} }
} }
return ApiResult.Success();
return Ok(new {code=0,data=true});
} }
/// <summary> /// <summary>
/// 分页查询 /// 分页查询
@@ -108,18 +106,13 @@ namespace dy.net.Controllers
PageRequestDto dto) PageRequestDto dto)
{ {
var (list, totalCount) = await dyCookieService.GetPagedAsync(dto.PageIndex, dto.PageSize); var (list, totalCount) = await dyCookieService.GetPagedAsync(dto.PageIndex, dto.PageSize);
return Ok(new return ApiResult.Success(new
{
code = 0,
data = new
{ {
data = list, data = list,
total = totalCount, total = totalCount,
pageIndex = dto.PageIndex, pageIndex = dto.PageIndex,
pageSize = dto.PageSize pageSize = dto.PageSize
} });
}
);
} }
@@ -131,7 +124,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> GetAllList() public async Task<IActionResult> GetAllList()
{ {
var follows = await douyinFollowService.GetGroupByCookieAsync(); var follows = await douyinFollowService.GetGroupByCookieAsync();
return Ok(new { code = 0, data = follows }); return ApiResult.Success(follows);
} }
/// <summary> /// <summary>
/// 新增用户Cookie /// 新增用户Cookie
@@ -143,10 +136,10 @@ namespace dy.net.Controllers
var result = await dyCookieService.Add(dyUserCookies); var result = await dyCookieService.Add(dyUserCookies);
if (result) if (result)
{ {
await ReStartJob(); ReStartJob();
return Ok(new { code = 0 }); return ApiResult.Success();
} }
return BadRequest(new { code = -1, message = "添加失败" }); return ApiResult.Fail("添加失败");
} }
/// <summary> /// <summary>
@@ -162,20 +155,20 @@ namespace dy.net.Controllers
var result = await dyCookieService.Add(dyUserCookies); var result = await dyCookieService.Add(dyUserCookies);
if (result) if (result)
{ {
await ReStartJob(); ReStartJob();
return Ok(new { code = 0 }); return ApiResult.Success();
} }
return BadRequest(new { code = -1, message = "添加失败" }); return ApiResult.Fail("添加失败");
} }
else else
{ {
var result = await dyCookieService.UpdateAsync(dyUserCookies); var result = await dyCookieService.UpdateAsync(dyUserCookies);
if (result) if (result)
{ {
await ReStartJob(); ReStartJob();
return Ok(new { code = 0 }); return ApiResult.Success();
} }
return BadRequest(new { code = -1, message = "更新失败" }); return ApiResult.Fail("更新失败");
} }
} }
@@ -189,16 +182,16 @@ namespace dy.net.Controllers
var count = await dyCookieService.DeleteByIdsAsync(new List<string> { id }); var count = await dyCookieService.DeleteByIdsAsync(new List<string> { id });
if (count > 0) if (count > 0)
{ {
await ReStartJob(); ReStartJob();
} }
return Ok(new { code = 0, deletedCount = count }); return ApiResult.Success(count);
} }
[HttpGet("GetConfig")] [HttpGet("GetConfig")]
public IActionResult GetConfig() public IActionResult GetConfig()
{ {
var data = commonService.GetConfig(); var data = commonService.GetConfig();
return Ok(new { code = 0, data = data }); return ApiResult.Success(data);
} }
[HttpPost("UpdateConfig")] [HttpPost("UpdateConfig")]
@@ -207,9 +200,9 @@ namespace dy.net.Controllers
var data = await commonService.UpdateConfig(config); var data = await commonService.UpdateConfig(config);
if (data) if (data)
{ {
await ReStartJob(); ReStartJob();
} }
return Ok(new { code = 0, data = data }); return ApiResult.Success(data);
} }
/// <summary> /// <summary>
@@ -223,11 +216,11 @@ namespace dy.net.Controllers
var config = commonService.GetConfig(); var config = commonService.GetConfig();
if (config != null) if (config != null)
await quartzJobService.InitOrReStartAllJobs(config.Cron.ToString()); await quartzJobService.InitOrReStartAllJobs(config.Cron.ToString());
return Ok(new { code = 0, error = "" }); return ApiResult.Success();
} }
private async Task ReStartJob() private void ReStartJob()
{ {
var config = commonService.GetConfig(); var config = commonService.GetConfig();
if (config != null) if (config != null)
@@ -241,7 +234,7 @@ namespace dy.net.Controllers
[HttpGet("mytag")] [HttpGet("mytag")]
public async Task<IActionResult> GetMyTag() public async Task<IActionResult> GetMyTag()
{ {
return Ok(new { code = 0, data = Appsettings.Get("tagName") }); return ApiResult.Success(Appsettings.Get("tagName"));
} }
[HttpGet("checktag")] [HttpGet("checktag")]
@@ -255,7 +248,7 @@ namespace dy.net.Controllers
} }
else else
{ {
return BadRequest(new { code = -1, message = "请求失败" }); return ApiResult.Fail("请求失败");
} }
} }
} }
+10 -30
View File
@@ -34,25 +34,17 @@ namespace dy.net.Controllers
{ {
if (string.IsNullOrWhiteSpace(dto.MySelfId)) if (string.IsNullOrWhiteSpace(dto.MySelfId))
{ {
return Ok(new return ApiResult.Success(new { });
{
code = 0,
data = new { }
});
} }
var (list, totalCount) = await _douyinFollowService.GetPagedAsync(dto); var (list, totalCount) = await _douyinFollowService.GetPagedAsync(dto);
return Ok(new
{ return ApiResult.Success(new
code = 0,
data = new
{ {
data = list, data = list,
total = totalCount, total = totalCount,
pageIndex = dto.PageIndex, pageIndex = dto.PageIndex,
pageSize = dto.PageSize pageSize = dto.PageSize
} });
}
);
} }
/// <summary> /// <summary>
/// 重新同步-单次 /// 重新同步-单次
@@ -64,13 +56,13 @@ namespace dy.net.Controllers
//后台异步 //后台异步
_douyinQuartzJobService.StartFollowJobOnceAsync(); _douyinQuartzJobService.StartFollowJobOnceAsync();
await Task.Delay(1000); await Task.Delay(1000);
return Ok(new { code = 0 }); return ApiResult.Success();
} }
[HttpPost("add")] [HttpPost("add")]
public async Task<IActionResult> AddFollow(DouyinFollowed followed) public async Task<IActionResult> AddFollow(DouyinFollowed followed)
{ {
var res = await _douyinFollowService.AddAsync(followed); var res = await _douyinFollowService.AddAsync(followed);
return Ok(new { code = res ? 0 : -1, msg = res ? "" : "添加失败,或者已存在相同secuid和uid" }); return ApiResult.SuccOrFail(res,"", res ? "" : "添加失败,或者已存在相同secuid和uid");
} }
/// <summary> /// <summary>
@@ -88,29 +80,17 @@ namespace dy.net.Controllers
{ {
if (!DouyinFileNameHelper.IsValidWithoutSpecialChars(dto.SavePath)) if (!DouyinFileNameHelper.IsValidWithoutSpecialChars(dto.SavePath))
{ {
return Ok(new return ApiResult.Fail("请输入有效文件夹名称(字母数字中文简体)");
{
code = -1,
msg = "请输入有效文件夹名称(字母数字中文简体)"
});
} }
if (dto.SavePath.Length > 15) if (dto.SavePath.Length > 15)
{ {
return Ok(new return ApiResult.Fail("请输入有效文件夹名称(最长15)");
{
code = -1,
msg = "请输入有效文件夹名称(最长15)"
});
} }
} }
} }
var result= await _douyinFollowService.OpenOrCloseSync(dto); var result= await _douyinFollowService.OpenOrCloseSync(dto);
return Ok(new return ApiResult.SuccOrFail(result, result);
{
code = result ? 0 : -1,
data = result
});
} }
/// <summary> /// <summary>
@@ -129,7 +109,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> DeleteFollow(FollowUpdateDto dto) public async Task<IActionResult> DeleteFollow(FollowUpdateDto dto)
{ {
var result= await _douyinFollowService.DeleteFollow(dto); var result= await _douyinFollowService.DeleteFollow(dto);
return Ok(new { code = result ? 0 : -1, data = result }); return ApiResult.SuccOrFail(result, result);
} }
} }
} }
+2 -2
View File
@@ -52,11 +52,11 @@ namespace dy.net.Controllers
{ {
var _logDirectory = Path.Combine(Directory.GetCurrentDirectory(), "logs"); var _logDirectory = Path.Combine(Directory.GetCurrentDirectory(), "logs");
var files = logInfoService.GetLogFiles(_logDirectory); var files = logInfoService.GetLogFiles(_logDirectory);
return Ok(new {code=0,data=files}); return ApiResult.Success(files);
} }
catch (Exception ex) catch (Exception ex)
{ {
return StatusCode(500, new { message = "获取日志列表失败", error = ex.Message }); return ApiResult.Fail("获取日志列表失败," + ex.Message);
} }
} }
+19 -29
View File
@@ -28,16 +28,12 @@ namespace dy.net.Controllers
public async Task<IActionResult> GetPagedAsync(DouyinVideoPageRequestDto dto) public async Task<IActionResult> GetPagedAsync(DouyinVideoPageRequestDto dto)
{ {
var (list, totalCount) = await douyinVideoService.GetPagedAsync(dto); var (list, totalCount) = await douyinVideoService.GetPagedAsync(dto);
return Ok(new return ApiResult.Success(new
{
code = 0,
data = new
{ {
data = list, data = list,
total = totalCount, total = totalCount,
pageIndex = dto.PageIndex, pageIndex = dto.PageIndex,
pageSize = dto.PageSize pageSize = dto.PageSize
}
}); });
} }
@@ -50,11 +46,7 @@ namespace dy.net.Controllers
public async Task<IActionResult> GetStaticsAsync() public async Task<IActionResult> GetStaticsAsync()
{ {
var data = await douyinVideoService.GetStatics(); var data = await douyinVideoService.GetStatics();
return Ok(new return ApiResult.Success(data);
{
code = 0,
data
});
} }
/// <summary> /// <summary>
@@ -72,13 +64,13 @@ namespace dy.net.Controllers
if (viedo == null) if (viedo == null)
{ {
return NotFound($"视频不存在:{vid}"); return ApiResult.Fail($"视频不存在:{vid}");
} }
return PlayViedo(viedo); return PlayViedo(viedo);
} }
catch (Exception ex) catch (Exception ex)
{ {
return StatusCode(500, $"视频加载失败:{ex.Message}"); return ApiResult.Fail($"视频加载失败:{ex.Message}");
} }
} }
@@ -91,7 +83,7 @@ namespace dy.net.Controllers
// 2. 验证文件是否存在 // 2. 验证文件是否存在
if (!System.IO.File.Exists(videoFullPath)) if (!System.IO.File.Exists(videoFullPath))
{ {
return NotFound($"视频文件不存在:{videoFullPath}"); return ApiResult.Fail($"视频文件不存在:{videoFullPath}");
} }
// 3. 获取文件信息(大小、类型) // 3. 获取文件信息(大小、类型)
@@ -141,20 +133,20 @@ namespace dy.net.Controllers
if (viedo == null) if (viedo == null)
{ {
return NotFound($"视频不存在:{vid}"); return ApiResult.Fail($"视频不存在:{vid}");
} }
var expectedKey = (viedo.FileHash + viedo.AuthorId).Md5(); var expectedKey = (viedo.FileHash + viedo.AuthorId).Md5();
if (expectedKey != k) if (expectedKey != k)
{ {
return NotFound($"视频地址无效"); return ApiResult.Fail($"视频地址无效");
} }
return PlayViedo(viedo); return PlayViedo(viedo);
} }
catch (Exception ex) catch (Exception ex)
{ {
return StatusCode(500, $"视频加载失败:{ex.Message}"); return ApiResult.Fail($"视频加载失败:{ex.Message}");
} }
} }
@@ -187,18 +179,18 @@ namespace dy.net.Controllers
{ {
if (dto == null) if (dto == null)
{ {
return Ok(new { code = -1, data = false }); return ApiResult.Fail("参数错误");
} }
else else
{ {
var result = await douyinVideoService.ReDownloadViedoAsync(dto); var result = await douyinVideoService.ReDownloadViedoAsync(dto);
if (result) if (result)
{ {
return Ok(new { code = 0, data = true }); return ApiResult.Success(true);
} }
else else
{ {
return Ok(new { code = -1, data = false }); return ApiResult.Fail("错误");
} }
} }
} }
@@ -212,14 +204,14 @@ namespace dy.net.Controllers
{ {
if (string.IsNullOrWhiteSpace(vid)) if (string.IsNullOrWhiteSpace(vid))
{ {
return Ok(new { code = -1, data = false }); return ApiResult.Fail("参数错误");
} }
else else
{ {
var video = await douyinVideoService.GetById(vid); var video = await douyinVideoService.GetById(vid);
if (video == null) if (video == null)
{ {
return Ok(new { code = -1, data = false }); return ApiResult.Fail("请求失败");
} }
else else
{ {
@@ -233,13 +225,13 @@ namespace dy.net.Controllers
VideoTitle = video.VideoTitle, VideoTitle = video.VideoTitle,
VideoSavePath = video.VideoSavePath VideoSavePath = video.VideoSavePath
}); });
Serilog.Log.Debug($"前面的日志,你错了,这条视频是永久删除..哈哈--{video.VideoTitle}");
return Ok(new { code = 0, data = true }); Serilog.Log.Debug($"前面的日志,你错了,这条视频是永久删除..哈哈--{video.VideoTitle}");
return ApiResult.Success();
} }
else else
{ {
return Ok(new { code = -1, data = false }); return ApiResult.Fail();
} }
} }
@@ -254,7 +246,7 @@ namespace dy.net.Controllers
[HttpGet("vdelete/get")] [HttpGet("vdelete/get")]
public async Task<IActionResult> GetDeleteVideo() public async Task<IActionResult> GetDeleteVideo()
{ {
return Ok(new { code = 0, data = await douyinCommonService.GetDouyinDeleteVideos() }); return ApiResult.Success(await douyinCommonService.GetDouyinDeleteVideos());
} }
/// <summary> /// <summary>
@@ -263,11 +255,9 @@ namespace dy.net.Controllers
/// <param name="top"></param> /// <param name="top"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("top{top}")] [HttpGet("top{top}")]
public async Task<IActionResult> GetLast([FromRoute]int top = 5) public async Task<IActionResult> GetLastSyncTop([FromRoute]int top = 5)
{ {
var data =await douyinVideoService.GetLastTop(top); return ApiResult.Success(await douyinVideoService.GetLastSyncTop(top));
return Ok(new { code = 0, data = data });
} }
} }
} }
+121 -59
View File
@@ -1,73 +1,67 @@
using dy.net.extension; using dy.net.extension;
using dy.net.service; using dy.net.service;
using dy.net.utils; using dy.net.utils;
using Serilog; using Serilog;
using System.Drawing;
using System.Text; using System.Text;
namespace dy.net namespace dy.net
{ {
public class Program public class Program
{ {
// 常量定义 // 常量定义
private static string DefaultListenUrl = "http://*:10101"; private static string DefaultListenUrl = "http://*:10101";
private const string SpaRootPath = "app/dist"; private const string SpaRootPath = "app/dist";
private const string SpaSourcePath = "app/"; private const string SpaSourcePath = "app/";
private const string SwaggerDocTitle = "dy.net WebApi Docs"; private const string SwaggerDocTitle = "dy.net WebApi Docs";
/// <summary> /// <summary>
/// 打包时注意,如果是false,前端不允许修改开启下载图片和视频的选项 /// 打包时注意,如果是false,前端不允许修改开启下载图片和视频的选项
/// </summary> /// </summary>
public static void Main(string[] args) public static void Main(string[] args)
{ {
//Console.ForegroundColor = ConsoleColor.Yellow;
// 初始化编码提供器
// 初始化编码提供器
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// 构建Web应用 // 构建Web应用
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
//from docker yaml file 环境变量 或者 dockerfile 或appsettings.json //from docker yaml file 环境变量 或者 dockerfile 或appsettings.json
DefaultListenUrl = builder.Configuration.GetValue<string>(SystemStaticUtil.ASPNETCORE_URLS) ?? DefaultListenUrl; DefaultListenUrl = builder.Configuration.GetValue<string>(SystemStaticUtil.ASPNETCORE_URLS) ?? DefaultListenUrl;
var isDevelopment = builder.Environment.IsDevelopment(); var isDevelopment = builder.Environment.IsDevelopment();
// 配置主机 // 配置主机
ConfigureHost(builder, isDevelopment); ConfigureHost(builder, isDevelopment);
// 配置服务 // 配置服务
ConfigureServices(builder.Services, builder.Configuration, builder.Environment); ConfigureServices(builder.Services, builder.Configuration, builder.Environment);
// 构建应用 // 构建应用
var app = builder.Build(); var app = builder.Build();
Log.Debug("ffmpeg is on"); Log.Debug("ffmpeg is on");
// 配置中间件 // 配置中间件
ConfigureMiddleware(app, builder.Environment); ConfigureMiddleware(app, builder.Environment);
// 初始化应用服务 // 初始化应用服务
InitApplicationServices(app, isDevelopment); InitApplicationServices(app, isDevelopment);
Serilog.Log.Debug("dy.sync service is starting..."); Serilog.Log.Debug("dy.sync service is starting...");
Log.Debug("dy.sync service is started successfully"); Log.Debug("dy.sync service is started successfully");
Console.WriteLine("------------------------------------------------------------------------"); Console.WriteLine();
Console.WriteLine(@" __ \\ \ / ___|\ \ / \ | ___|
| |\ / \___ \ \ / \ | |
| | | | | |\ | |
____/ _|_)_____/ _| _| \_|\____|
");
//Console.ResetColor();
app.Run(); app.Run();
} }
/// <summary> /// <summary>
/// 配置主机设置 /// 配置主机设置
/// </summary> /// </summary>
private static void ConfigureHost(WebApplicationBuilder builder, bool isDevelopment) private static void ConfigureHost(WebApplicationBuilder builder, bool isDevelopment)
{ {
// 设置监听地址 // 设置监听地址
builder.WebHost.UseUrls(DefaultListenUrl); builder.WebHost.UseUrls(DefaultListenUrl);
// 配置配置文件 // 配置配置文件
builder.Host.ConfigureAppConfiguration((context, config) => builder.Host.ConfigureAppConfiguration((context, config) =>
{ {
config.SetBasePath(Directory.GetCurrentDirectory()) config.SetBasePath(Directory.GetCurrentDirectory())
@@ -75,7 +69,7 @@ ____/ _|_)_____/ _| _| \_|\____|
.AddEnvironmentVariables(); .AddEnvironmentVariables();
}); });
// 配置日志 // 配置日志
builder.Host.ConfigureLogging(logging => logging.ClearProviders()) builder.Host.ConfigureLogging(logging => logging.ClearProviders())
.UseSerilog(); .UseSerilog();
@@ -83,86 +77,83 @@ ____/ _|_)_____/ _| _| \_|\____|
} }
/// <summary> /// <summary>
/// 配置依赖注入服务 /// 配置依赖注入服务
/// </summary> /// </summary>
private static void ConfigureServices(IServiceCollection services, IConfiguration config, IWebHostEnvironment environment) private static void ConfigureServices(IServiceCollection services, IConfiguration config, IWebHostEnvironment environment)
{ {
PrintApp();
services.AddSingleton(new Appsettings (config)); services.AddSingleton(new Appsettings (config));
// 雪花ID生成器 // 雪花ID生成器
services.AddSnowFlakeId(options => options.WorkId = new Random().Next(1, 100)); services.AddSnowFlakeId(options => options.WorkId = new Random().Next(1, 100));
// MVC控制器
services.AddControllers();
// HTTP客户端
// MVC控制器+异常拦截器
services.AddControllers().AddGlobalExceptionFilter();
// HTTP客户端
services.AddHttpClients(); services.AddHttpClients();
// 数据库 // 数据库
services.AddSqlsugar(config); services.AddSqlsugar(config);
// 定时任务 // 定时任务
services.AddQuartzService(); services.AddQuartzService();
// 仓储和服务注册 // 仓储和服务注册
services.AddServicesFromNamespace("dy.net.repository") services.AddServicesFromNamespace("dy.net.repository")
.AddServicesFromNamespace("dy.net.service"); .AddServicesFromNamespace("dy.net.service");
services.AddSingleton<FFmpegHelper>(); services.AddSingleton<FFmpegHelper>();
////下载图片合成视频-需要ffmpeg支持,镜像会很大。
//if (downImageVideo) // SPA静态文件支持
//{
// //根据配置动态加载dy.image程序集
// Assembly assembly = Assembly.LoadFrom(Path.Combine(AppContext.BaseDirectory, "dy.image.dll"));
// services.AddServicesFromNamespace("dy.image", assembly);
//}
// SPA静态文件支持
services.AddSpaStaticFiles(options => options.RootPath = SpaRootPath); services.AddSpaStaticFiles(options => options.RootPath = SpaRootPath);
// 开发环境启用Swagger // 开发环境启用Swagger
if (environment.IsDevelopment()) if (environment.IsDevelopment())
{ {
services.AddSwagger(); services.AddSwagger();
} }
// 响应压缩 // 响应压缩
services.AddResponseCompression(); services.AddResponseCompression();
// JWT认证 // JWT认证
services.ConfigureJwtAuthentication(); services.ConfigureJwtAuthentication();
} }
/// <summary> /// <summary>
/// 配置中间件 /// 配置中间件
/// </summary> /// </summary>
private static void ConfigureMiddleware(WebApplication app, IWebHostEnvironment environment) private static void ConfigureMiddleware(WebApplication app, IWebHostEnvironment environment)
{ {
// 响应压缩 // 响应压缩
app.UseResponseCompression(); app.UseResponseCompression();
// 开发环境启用SwaggerUI // 开发环境启用SwaggerUI
if (environment.IsDevelopment()) if (environment.IsDevelopment())
{ {
app.UseCustomSwaggerUI(options => options.Title = SwaggerDocTitle); app.UseCustomSwaggerUI(options => options.Title = SwaggerDocTitle);
} }
// 路由 // 路由
app.UseRouting(); app.UseRouting();
// 认证授权 // 认证授权
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
// 配置文件上传路径 // 配置文件上传路径
//ConfigureUploadPath(app, isDevelopment); //ConfigureUploadPath(app, isDevelopment);
// API路由映射 // API路由映射
app.MapControllers(); app.MapControllers();
app.UseStaticFiles(); app.UseStaticFiles();
// 生产环境启用SPA // 生产环境启用SPA
if (!environment.IsDevelopment()) if (!environment.IsDevelopment())
{ {
app.UseSpaStaticFiles(); app.UseSpaStaticFiles();
@@ -171,7 +162,7 @@ ____/ _|_)_____/ _| _| \_|\____|
} }
/// <summary> /// <summary>
/// 初始化应用服务数据 /// 初始化应用服务数据
/// </summary> /// </summary>
private static void InitApplicationServices(WebApplication app,bool isDevelopment) private static void InitApplicationServices(WebApplication app,bool isDevelopment)
{ {
@@ -180,26 +171,26 @@ ____/ _|_)_____/ _| _| \_|\____|
try try
{ {
// 初始化用户 // 初始化用户
var userService = services.GetRequiredService<AdminUserService>(); var userService = services.GetRequiredService<AdminUserService>();
userService.InitUser(); userService.InitUser();
// 初始化Cookie // 初始化Cookie
var cookieService = services.GetRequiredService<DouyinCookieService>(); var cookieService = services.GetRequiredService<DouyinCookieService>();
cookieService.InitCookie(); cookieService.InitCookie();
// 初始化配置 // 初始化配置
var commonService = services.GetRequiredService<DouyinCommonService>(); var commonService = services.GetRequiredService<DouyinCommonService>();
var config = commonService.InitConfig(); var config = commonService.InitConfig();
// 更新视频类型--兼容老版本 // 更新视频类型--兼容老版本
commonService.UpdateCollectViedoType(); commonService.UpdateCollectViedoType();
// 重置博主作品同步状态为未同步 // 重置博主作品同步状态为未同步
commonService.UpdateAllCookieSyncedToZero(); commonService.UpdateAllCookieSyncedToZero();
if (!isDevelopment) if (!isDevelopment)
{ {
// 启动定时任务 // 启动定时任务
var quartzJobService = services.GetRequiredService<DouyinQuartzJobService>(); var quartzJobService = services.GetRequiredService<DouyinQuartzJobService>();
quartzJobService.InitOrReStartAllJobs(config?.Cron <= 0 ? "30" : config.Cron.ToString()); quartzJobService.InitOrReStartAllJobs(config?.Cron <= 0 ? "30" : config.Cron.ToString());
} }
@@ -212,7 +203,78 @@ ____/ _|_)_____/ _| _| \_|\____|
} }
private static void PrintApp()
{
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.WriteLine();
// 步骤1:定义原始ASCII艺术字行(无缩进)
List<string> originalArtLines = new List<string>
{
" __ __ ",
" ___/ /_ __ ___ __ _____ ____ ___ ___ / /_",
"/ _ / // / (_-</ // / _ \\__/ / _ \\/ -_) __/",
"\\_,_/\\_, (_)___/\\_, /_//_/\\__(_)_//_/\\__/\\__/ ",
" /___/ /___/ "
};
// 步骤2:设置缩进字符数(可自由修改:4、8、10 等)
int indentCount = 4;
string indent = new string(' ', indentCount); // 生成对应数量的空格
// 步骤3:给每行添加缩进
List<string> indentedArtLines = new List<string>();
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);
//string asciiArt = @"=================================================================================================================";
//string asciiArt = $@"——————————————————————{DateTime.Now:yyyy-MM-dd HH:mm:ss}——————————————————————";
//foreach (char ch in asciiArt)
//{
// Console.Write(ch);
// Thread.Sleep(2);
//}
Console.WriteLine();
Console.ResetColor();
}
} }
} }
@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\</_PublishTargetUrl> <_PublishTargetUrl>E:\code\dysync\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2025-12-19T01:50:16.9517676Z||;True|2025-12-19T09:49:47.0871734+08:00||;False|2025-12-19T09:49:36.7638757+08:00||;True|2025-12-19T09:35:13.2489248+08:00||;True|2025-12-14T19:09:59.9031104+08:00||;True|2025-12-13T21:21:10.0022707+08:00||;True|2025-12-11T22:07:16.6229994+08:00||;True|2025-12-11T22:05:56.7363206+08:00||;True|2025-12-11T22:01:07.5862406+08:00||;True|2025-12-11T22:00:43.5796594+08:00||;True|2025-12-08T21:20:37.8369271+08:00||;False|2025-12-08T21:20:21.1646252+08:00||;True|2025-12-08T20:51:50.6845619+08:00||;True|2025-12-08T16:43:45.2425324+08:00||;False|2025-12-08T16:42:23.0308163+08:00||;True|2025-12-08T16:41:52.4103868+08:00||;True|2025-12-08T16:41:49.8972006+08:00||;False|2025-12-08T16:41:39.5343442+08:00||;True|2025-12-08T12:40:19.2430740+08:00||;True|2025-12-08T12:02:30.6005542+08:00||;True|2025-12-08T11:34:29.6673185+08:00||;False|2025-12-08T11:30:56.2857042+08:00||;True|2025-12-08T10:52:43.7427594+08:00||;True|2025-12-08T07:05:03.2845531+08:00||;True|2025-12-07T23:02:10.0037815+08:00||;True|2025-12-07T22:48:25.7859648+08:00||;True|2025-12-07T20:49:13.6683281+08:00||;True|2025-12-07T08:47:30.1236366+08:00||;True|2025-12-06T13:14:32.4410202+08:00||;True|2025-12-06T13:07:29.7182102+08:00||;True|2025-12-06T13:05:46.2855366+08:00||;False|2025-12-06T13:05:40.3550904+08:00||;True|2025-12-06T13:03:47.8773880+08:00||;True|2025-12-06T13:03:28.9521030+08:00||;True|2025-12-05T23:11:51.5026151+08:00||;True|2025-12-05T12:46:26.1415079+08:00||;False|2025-12-05T12:46:19.1274332+08:00||;True|2025-12-05T09:04:36.7111717+08:00||;True|2025-12-05T08:22:51.7343317+08:00||;True|2025-12-05T08:20:32.0383739+08:00||;True|2025-12-04T21:58:29.4112766+08:00||;True|2025-12-04T21:58:10.0382218+08:00||;True|2025-12-04T21:57:55.3894059+08:00||;True|2025-12-04T21:10:38.8943797+08:00||;True|2025-12-04T21:09:31.5024569+08:00||;True|2025-12-04T08:22:47.9617427+08:00||;False|2025-12-04T08:22:41.3759733+08:00||;True|2025-12-04T08:14:02.2478893+08:00||;True|2025-12-04T07:57:00.2208139+08:00||;True|2025-12-03T23:58:13.3693303+08:00||;True|2025-12-03T23:57:40.4257893+08:00||;True|2025-12-03T23:56:38.8717769+08:00||;True|2025-12-03T23:56:24.0663568+08:00||;False|2025-12-03T23:55:36.1902974+08:00||;True|2025-12-03T23:51:30.6688504+08:00||;True|2025-12-03T23:34:17.1648971+08:00||;False|2025-12-03T23:34:07.7649161+08:00||;True|2025-12-03T22:32:56.2435003+08:00||;True|2025-12-03T22:27:45.6059666+08:00||;True|2025-12-03T15:55:28.0186597+08:00||;False|2025-12-03T15:54:17.5032724+08:00||;True|2025-12-03T15:53:10.2273509+08:00||;True|2025-12-02T22:11:37.4645042+08:00||;False|2025-12-02T22:10:47.1320259+08:00||;True|2025-12-02T14:39:58.8932130+08:00||;True|2025-12-02T14:36:37.1529072+08:00||;True|2025-12-02T12:58:22.0951548+08:00||;True|2025-12-02T09:30:33.7066474+08:00||;True|2025-12-02T09:30:14.5481844+08:00||;True|2025-12-02T09:30:00.3123364+08:00||;False|2025-12-02T09:29:54.4615520+08:00||;True|2025-12-02T09:13:01.7995414+08:00||;False|2025-12-02T09:12:55.8360281+08:00||;True|2025-12-02T09:12:31.0156791+08:00||;True|2025-12-02T08:55:11.3773395+08:00||;True|2025-12-02T08:53:21.3927713+08:00||;False|2025-12-02T08:48:55.8638037+08:00||;True|2025-12-02T07:29:25.2192447+08:00||;False|2025-12-02T07:29:10.2504665+08:00||;True|2025-12-02T07:28:29.0769286+08:00||;True|2025-12-01T21:53:07.6474834+08:00||;True|2025-12-01T21:44:28.1674315+08:00||;True|2025-12-01T21:18:47.2119609+08:00||;True|2025-12-01T20:51:19.9948301+08:00||;True|2025-12-01T20:50:36.9904697+08:00||;True|2025-12-01T20:44:10.1695142+08:00||;True|2025-12-01T19:27:58.0479456+08:00||;True|2025-12-01T19:16:02.2288214+08:00||;False|2025-12-01T19:15:56.0372115+08:00||;True|2025-12-01T19:15:16.4854821+08:00||;False|2025-12-01T19:15:06.7001019+08:00||;True|2025-12-01T17:10:38.9739466+08:00||;False|2025-12-01T17:10:18.8928139+08:00||;True|2025-12-01T17:03:59.3171589+08:00||;True|2025-12-01T17:03:12.5681656+08:00||;True|2025-12-01T16:42:51.4415025+08:00||;True|2025-12-01T01:29:59.6975567+08:00||;True|2025-12-01T01:29:45.1898652+08:00||;False|2025-12-01T01:29:33.1787721+08:00||;True|2025-12-01T01:27:33.1297605+08:00||;</History> <History>True|2025-12-20T04:16:22.5224516Z||;True|2025-12-19T09:50:16.9517676+08:00||;True|2025-12-19T09:49:47.0871734+08:00||;False|2025-12-19T09:49:36.7638757+08:00||;True|2025-12-19T09:35:13.2489248+08:00||;True|2025-12-14T19:09:59.9031104+08:00||;True|2025-12-13T21:21:10.0022707+08:00||;True|2025-12-11T22:07:16.6229994+08:00||;True|2025-12-11T22:05:56.7363206+08:00||;True|2025-12-11T22:01:07.5862406+08:00||;True|2025-12-11T22:00:43.5796594+08:00||;True|2025-12-08T21:20:37.8369271+08:00||;False|2025-12-08T21:20:21.1646252+08:00||;True|2025-12-08T20:51:50.6845619+08:00||;True|2025-12-08T16:43:45.2425324+08:00||;False|2025-12-08T16:42:23.0308163+08:00||;True|2025-12-08T16:41:52.4103868+08:00||;True|2025-12-08T16:41:49.8972006+08:00||;False|2025-12-08T16:41:39.5343442+08:00||;True|2025-12-08T12:40:19.2430740+08:00||;True|2025-12-08T12:02:30.6005542+08:00||;True|2025-12-08T11:34:29.6673185+08:00||;False|2025-12-08T11:30:56.2857042+08:00||;True|2025-12-08T10:52:43.7427594+08:00||;True|2025-12-08T07:05:03.2845531+08:00||;True|2025-12-07T23:02:10.0037815+08:00||;True|2025-12-07T22:48:25.7859648+08:00||;True|2025-12-07T20:49:13.6683281+08:00||;True|2025-12-07T08:47:30.1236366+08:00||;True|2025-12-06T13:14:32.4410202+08:00||;True|2025-12-06T13:07:29.7182102+08:00||;True|2025-12-06T13:05:46.2855366+08:00||;False|2025-12-06T13:05:40.3550904+08:00||;True|2025-12-06T13:03:47.8773880+08:00||;True|2025-12-06T13:03:28.9521030+08:00||;True|2025-12-05T23:11:51.5026151+08:00||;True|2025-12-05T12:46:26.1415079+08:00||;False|2025-12-05T12:46:19.1274332+08:00||;True|2025-12-05T09:04:36.7111717+08:00||;True|2025-12-05T08:22:51.7343317+08:00||;True|2025-12-05T08:20:32.0383739+08:00||;True|2025-12-04T21:58:29.4112766+08:00||;True|2025-12-04T21:58:10.0382218+08:00||;True|2025-12-04T21:57:55.3894059+08:00||;True|2025-12-04T21:10:38.8943797+08:00||;True|2025-12-04T21:09:31.5024569+08:00||;True|2025-12-04T08:22:47.9617427+08:00||;False|2025-12-04T08:22:41.3759733+08:00||;True|2025-12-04T08:14:02.2478893+08:00||;True|2025-12-04T07:57:00.2208139+08:00||;True|2025-12-03T23:58:13.3693303+08:00||;True|2025-12-03T23:57:40.4257893+08:00||;True|2025-12-03T23:56:38.8717769+08:00||;True|2025-12-03T23:56:24.0663568+08:00||;False|2025-12-03T23:55:36.1902974+08:00||;True|2025-12-03T23:51:30.6688504+08:00||;True|2025-12-03T23:34:17.1648971+08:00||;False|2025-12-03T23:34:07.7649161+08:00||;True|2025-12-03T22:32:56.2435003+08:00||;True|2025-12-03T22:27:45.6059666+08:00||;True|2025-12-03T15:55:28.0186597+08:00||;False|2025-12-03T15:54:17.5032724+08:00||;True|2025-12-03T15:53:10.2273509+08:00||;True|2025-12-02T22:11:37.4645042+08:00||;False|2025-12-02T22:10:47.1320259+08:00||;True|2025-12-02T14:39:58.8932130+08:00||;True|2025-12-02T14:36:37.1529072+08:00||;True|2025-12-02T12:58:22.0951548+08:00||;True|2025-12-02T09:30:33.7066474+08:00||;True|2025-12-02T09:30:14.5481844+08:00||;True|2025-12-02T09:30:00.3123364+08:00||;False|2025-12-02T09:29:54.4615520+08:00||;True|2025-12-02T09:13:01.7995414+08:00||;False|2025-12-02T09:12:55.8360281+08:00||;True|2025-12-02T09:12:31.0156791+08:00||;True|2025-12-02T08:55:11.3773395+08:00||;True|2025-12-02T08:53:21.3927713+08:00||;False|2025-12-02T08:48:55.8638037+08:00||;True|2025-12-02T07:29:25.2192447+08:00||;False|2025-12-02T07:29:10.2504665+08:00||;True|2025-12-02T07:28:29.0769286+08:00||;True|2025-12-01T21:53:07.6474834+08:00||;True|2025-12-01T21:44:28.1674315+08:00||;True|2025-12-01T21:18:47.2119609+08:00||;True|2025-12-01T20:51:19.9948301+08:00||;True|2025-12-01T20:50:36.9904697+08:00||;True|2025-12-01T20:44:10.1695142+08:00||;True|2025-12-01T19:27:58.0479456+08:00||;True|2025-12-01T19:16:02.2288214+08:00||;False|2025-12-01T19:15:56.0372115+08:00||;True|2025-12-01T19:15:16.4854821+08:00||;False|2025-12-01T19:15:06.7001019+08:00||;True|2025-12-01T17:10:38.9739466+08:00||;False|2025-12-01T17:10:18.8928139+08:00||;True|2025-12-01T17:03:59.3171589+08:00||;True|2025-12-01T17:03:12.5681656+08:00||;True|2025-12-01T16:42:51.4415025+08:00||;True|2025-12-01T01:29:59.6975567+08:00||;True|2025-12-01T01:29:45.1898652+08:00||;False|2025-12-01T01:29:33.1787721+08:00||;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+4 -4
View File
@@ -96,8 +96,8 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
| 镜像标签 | 架构 | | 镜像标签 | 架构 |
| ----------------- | -------------- | | ----------------- | -------------- |
| `beta_1.8.9` | x86_64 (amd64) | | `beta_1.9.0` | x86_64 (amd64) |
| `arm_1.8.9` | ARM64 | | `arm_1.9.0` | ARM64 |
### 最新镜像查看 ### 最新镜像查看
[镜像列表](http://nas.synology2023.online:10108/api/docker/dysync/1) [镜像列表](http://nas.synology2023.online:10108/api/docker/dysync/1)
@@ -115,7 +115,7 @@ docker run -d --restart=always \
-v /opt/dysync/uper:/app/uper \ -v /opt/dysync/uper:/app/uper \
-p 10103:10101 \ -p 10103:10101 \
--name dysync2025 \ --name dysync2025 \
ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_1.8.9 ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_1.9.0
# 注意:-p 后面的容器端口,可以用环境变量类似:ASPNETCORE_URLS = http://+:10108 指定 # 注意:-p 后面的容器端口,可以用环境变量类似:ASPNETCORE_URLS = http://+:10108 指定
``` ```
@@ -129,7 +129,7 @@ version: '3.8'
services: services:
dysync: dysync:
image: ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_1.8.9 image: ccr.ccs.tencentyun.com/jianzhichu/dysync:beta_1.9.0
container_name: dysync2025 # 容器名称 container_name: dysync2025 # 容器名称
restart: unless-stopped # 始终重启容器,除非容器被手动停止或Docker服务停止 restart: unless-stopped # 始终重启容器,除非容器被手动停止或Docker服务停止
ports: ports:
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"dbconn": "", "dbconn": "",
//"tagName": "arm_1.8.9", //"tagName": "arm_1.9.0",
//"tagName": "dev_1.8.9", //"tagName": "dev_1.9.0",
"tagName": "beta_1.8.9", "tagName": "beta_1.9.0",
"dbtype": "Sqlite" "dbtype": "Sqlite"
} }
+168
View File
@@ -0,0 +1,168 @@
using Microsoft.AspNetCore.Mvc;
using System.Text.Json.Serialization;
namespace dy.net.dto
{
public class DouyinApiResponse<T>
{
/// <summary>
/// 响应状态码(自定义业务码,非HTTP状态码)
/// </summary>
[JsonPropertyName("code")]
public int Code { get; set; }
/// <summary>
/// 响应数据
/// </summary>
[JsonPropertyName("data")]
public T Data { get; set; }
/// <summary>
/// 响应消息(成功/失败描述)
/// </summary>
[JsonPropertyName("msg")]
public string Msg { get; set; }
[JsonPropertyName("message")]
public string Message { get; set; }
[JsonPropertyName("error")]
public string Error { get; set; }
/// <summary>
/// 响应时间戳(UTC时间)
/// </summary>
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
/// <summary>
/// 响应状态码常量
/// </summary>
public static class ResponseCode
{
public const int Success = 0; // 操作成功
public const int ServerError = -1; // 服务器错误
}
/// <summary>
/// 直接返回 IActionResult 的API响应工具类
/// 无需控制器手动拼接 Ok()/BadRequest(),一步返回标准化响应
/// </summary>
public static class ApiResult
{
#region
/// <summary>
/// 成功响应(带数据)
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="data">响应数据</param>
/// <param name="message">成功消息(默认:操作成功)</param>
/// <returns>IActionResultHTTP 200</returns>
public static IActionResult Success<T>(T data, string message = "操作成功")
{
var response = new DouyinApiResponse<T>
{
Code = ResponseCode.Success,
Data = data,
Message = message,
Error = message,
Msg = message,
};
return new OkObjectResult(response); // HTTP 200
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="code"></param>
/// <param name="t"></param>
/// <param name="message"></param>
/// <returns></returns>
public static IActionResult SuccOrFail<T>(int code,T t,string message = "")
{
if (code == ResponseCode.Success)
{
return Success(t, message);
}
else
{
return Fail(message);
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="result"></param>
/// <param name="t"></param>
/// <param name="message"></param>
/// <returns></returns>
public static IActionResult SuccOrFail<T>(bool result, T t, string message = "")
{
if (result)
{
return Success(t, message);
}
else
{
return Fail(message);
}
}
/// <summary>
/// 成功响应(无数据)
/// </summary>
/// <param name="message">成功消息(默认:操作成功)</param>
/// <returns>IActionResultHTTP 200</returns>
public static IActionResult Success(string message = "操作成功")
{
return Success<object>(null, message);
}
#endregion
#region
/// <summary>
/// 失败响应
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="message">错误消息</param>
/// <param name="data">附加数据</param>
/// <returns>IActionResult</returns>
public static IActionResult Fail<T>(string message="请求失败", int businessCode = ResponseCode.ServerError, T data = default)
{
var response = new DouyinApiResponse<T>
{
Code = businessCode,
Data = data,
Message = message,
Error = message,
Msg = message,
};
return new OkObjectResult(response);
}
/// <summary>
/// 失败响应(无附加数据)
/// </summary>
/// <param name="message">错误消息</param>
/// <param name="businessCode">自定义业务码</param>
/// <returns>IActionResult</returns>
public static IActionResult Fail(string message, int businessCode = ResponseCode.ServerError)
{
return Fail<object>(message, businessCode);
}
/// <summary>
/// 失败响应(无附加数据)
/// </summary>
/// <param name="message">错误消息</param>
/// <returns>IActionResult</returns>
public static IActionResult Fail(string message="请求失败")
{
return Fail<object>(message, ResponseCode.ServerError);
}
#endregion
}
}
+66
View File
@@ -0,0 +1,66 @@
using dy.net.dto;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Net;
namespace dy.net.extension
{
public class DouyinExceptionFilter : IExceptionFilter
{
/// <summary>
/// 异常拦截核心方法
/// </summary>
public void OnException(ExceptionContext context)
{
// 1. 记录异常日志(区分业务异常和系统异常)
LogException(context);
// 2. 构建标准化响应结果
var response = BuildExceptionResponse(context.Exception);
// 3. 设置响应结果(终止异常传播)
context.Result = new ObjectResult(response);
context.ExceptionHandled = true;
}
/// <summary>
/// 记录异常日志
/// </summary>
private void LogException(ExceptionContext ex)
{
Serilog.Log.Error($"系统异常:{ex.Exception.Message},{ex.HttpContext.Request.Path}");
}
/// <summary>
/// 根据异常类型构建响应结果
/// </summary>
private static DouyinApiResponse<object> BuildExceptionResponse(Exception ex)
{
return new DouyinApiResponse<object>
{
Code = ResponseCode.ServerError,
Message = "服务器内部错误,请稍后重试",
Data = null,
Timestamp = DateTime.UtcNow
};
}
}
/// <summary>
/// 全局异常过滤器扩展(简化注册)
/// </summary>
public static class GlobalExceptionFilterExtensions
{
public static IMvcBuilder AddGlobalExceptionFilter(this IMvcBuilder mvcBuilder)
{
mvcBuilder.AddMvcOptions(options =>
{
options.Filters.Add<DouyinExceptionFilter>();
});
return mvcBuilder;
}
}
}
+2 -2
View File
@@ -17,9 +17,9 @@ namespace dy.net.repository
public async Task<List<DouyinVideoTopDto>> GetTopsOrderByCreateTime(int top) public async Task<List<DouyinVideoTopDto>> GetTopsOrderBySyncTime(int top)
{ {
return await Db.Queryable<DouyinVideo>().Select(x=>new DouyinVideoTopDto { Title=x.VideoTitle,Time=x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")}).Take(top).OrderByDescending(x=>x.Time).ToListAsync(); return await Db.Queryable<DouyinVideo>().Select(x=>new DouyinVideoTopDto { Title=x.VideoTitle,Time=x.SyncTime.ToString("yyyy-MM-dd HH:mm:ss")}).Take(top).OrderByDescending(x=>x.Time).ToListAsync();
} }
/// <summary> /// <summary>
/// ///
+2 -2
View File
@@ -313,9 +313,9 @@ namespace dy.net.service
public async Task<List<DouyinVideoTopDto>> GetLastTop(int top=5) public async Task<List<DouyinVideoTopDto>> GetLastSyncTop(int top=5)
{ {
return await _dyCollectVideoRepository.GetTopsOrderByCreateTime(top); return await _dyCollectVideoRepository.GetTopsOrderBySyncTime(top);
} }
} }