Files
douyin/Controllers/ConfigController.cs
T

494 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ClockSnowFlake;
using dy.net.dto;
using dy.net.model;
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
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ConfigController : ControllerBase
{
private readonly DouyinCookieService dyCookieService;
private readonly DouyinCommonService commonService;
private readonly DouyinQuartzJobService quartzJobService;
private readonly DouyinFollowService douyinFollowService;
private readonly DouyinCookieService douyinCookieService;
//// 定义允许上传的音频扩展名(小写)
//private readonly string[] _allowedAudioExtensions = { ".mp3", ".wav" };
//// 定义允许的音频 MIME 类型(增强验证)
//private readonly string[] _allowedAudioMimeTypes = {
// "audio/mpeg", "audio/wav"
//};
// 最大文件大小:20MB(可根据需求调整)
//private const long _maxFileSize = 20 * 1024 * 1024;
public ConfigController(DouyinCookieService dyCookieService, DouyinCommonService commonService, DouyinQuartzJobService quartzJobService, DouyinFollowService douyinFollowService, DouyinCookieService douyinCookieService)
{
this.dyCookieService = dyCookieService;
this.commonService = commonService;
this.quartzJobService = quartzJobService;
this.douyinFollowService = douyinFollowService;
this.douyinCookieService = douyinCookieService;
}
/// <summary>
/// 导出配置
/// </summary>
/// <returns></returns>
[HttpGet("exportConf")]
public async Task<IActionResult> ExportConf()
{
// 1. 组装导出数据
var dto = new AppConfigImportDto()
{
follows = await douyinFollowService.GetHandFollows(),
conf = commonService.GetConfig(),
cookies = await douyinCookieService.GetAllAsync()
};
return ApiResult.Success(dto);
}
/// <summary>
/// 导入配置
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("importConf")]
public async Task<IActionResult> 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)
{
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配置导入成功");
}
}
return ApiResult.Success();
}
/// <summary>
/// 分页查询
/// </summary>
/// <returns>分页结果</returns>
[HttpPost("paged")]
public async Task<IActionResult> GetPagedAsync(
PageRequestDto dto)
{
var (list, totalCount) = await dyCookieService.GetPagedAsync(dto.PageIndex, dto.PageSize);
return ApiResult.Success(new
{
data = list,
total = totalCount,
pageIndex = dto.PageIndex,
pageSize = dto.PageSize
});
}
/// <summary>
/// 查询所有用户Cookie
/// </summary>
/// <returns></returns>
[HttpGet("list")]
public async Task<IActionResult> GetAllList()
{
var follows = await douyinFollowService.GetGroupByCookieAsync();
return ApiResult.Success(follows);
}
/// <summary>
/// 是否已经初始化了
/// </summary>
/// <returns></returns>
[HttpGet("isInit")]
[AllowAnonymous]
public async Task<IActionResult> IsInit()
{
var init= await dyCookieService.IsInit();
return ApiResult.Success(init);
}
/// <summary>
/// 新增用户Cookie
/// </summary>
[HttpPost("add")]
public async Task<IActionResult> AddAsync([FromBody] DouyinCookie dyUserCookies)
{
var result = await dyCookieService.Add(dyUserCookies);
if (result)
{
ReStartJob();
return ApiResult.Success();
}
return ApiResult.Fail("添加失败");
}
/// <summary>
/// 非docker初始化
/// </summary>
[HttpPost("deskinit")]
[AllowAnonymous]
public async Task<IActionResult> DeskInitAsync([FromBody] DouyinCookie dyUserCookies)
{
dyUserCookies.Id = IdGener.GetLong().ToString();
if(string.IsNullOrWhiteSpace(dyUserCookies.SavePath))
{
return ApiResult.Fail("收藏存储路径不能为空");
}
if (!DouyinFileUtils.HasDirectoryReadWritePermission(dyUserCookies.SavePath))
{
return ApiResult.Fail($"请在飞牛应用设置里面将{dyUserCookies.SavePath}添加读写权限");
}
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 result = await dyCookieService.Add(dyUserCookies);
if (result)
{
return ApiResult.Success();
}
return ApiResult.Fail("添加失败");
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[HttpGet("appport")]
[AllowAnonymous]
public async Task<IActionResult> GetAppPort()
{
//return ApiResult.Success(10105);
return ApiResult.Success(string.IsNullOrWhiteSpace(Appsettings.Get("appPort"))?10101: Convert.ToInt32(Appsettings.Get("appPort")));
}
/// <summary>
/// 快速开启或停止
/// </summary>
[HttpPost("switch")]
public async Task<IActionResult> SwitchAsync([FromBody] DouyinCookieStopDto dto)
{
var result = await dyCookieService.Switch(dto);
if (result)
{
ReStartJob();
return ApiResult.Success();
}
return ApiResult.Fail("添加失败");
}
/// <summary>
/// 更新用户Cookie
/// </summary>
[HttpPost("update")]
public async Task<IActionResult> UpdateAsync([FromBody] DouyinCookie dyUserCookies)
{
if (dyUserCookies.Id == "0")
{
dyUserCookies.Id = IdGener.GetLong().ToString();
var result = await dyCookieService.Add(dyUserCookies);
if (result)
{
ReStartJob();
return ApiResult.Success();
}
return ApiResult.Fail("添加失败");
}
else
{
var result = await dyCookieService.UpdateAsync(dyUserCookies);
if (result)
{
ReStartJob();
return ApiResult.Success();
}
return ApiResult.Fail("更新失败");
}
}
/// <summary>
/// 批量删除用户Cookie
/// </summary>
[HttpGet("delete")]
public async Task<IActionResult> DeleteAsync(string id)
{
var count = await dyCookieService.DeleteByIdsAsync(new List<string> { id });
if (count > 0)
{
ReStartJob();
}
return ApiResult.Success(count);
}
[HttpGet("GetConfig")]
public IActionResult GetConfig()
{
var data = commonService.GetConfig();
return ApiResult.Success(data);
}
[HttpPost("UpdateConfig")]
public async Task<IActionResult> UpdateConfig(AppConfig config)
{
var data = await commonService.UpdateConfig(config);
if (data)
{
if (config.OnlySyncNew)
{
var d = await douyinCookieService.SetOnlySyncNew();
if (d)
Serilog.Log.Debug("仅同步新视频配置已生效,后续所有类型的视频同步将只会读取最近一页约20条数据");
}
ReStartJob();
}
return ApiResult.Success(data);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[HttpGet("ExecuteJobNow")]
//[Authorize]
public async Task<IActionResult> ExecuteJobNow()
{
var config = commonService.GetConfig();
if (config != null)
await quartzJobService.InitOrReStartAllJobs(config.Cron.ToString());
return ApiResult.Success();
}
private void ReStartJob()
{
var config = commonService.GetConfig();
if (config != null)
quartzJobService.InitOrReStartAllJobs(config.Cron.ToString());
//避免前端等待
}
/// <summary>
/// 镜像标签
/// </summary>
/// <returns></returns>
[HttpGet("mytag")]
public async Task<IActionResult> GetMyTag()
{
return ApiResult.Success(Appsettings.Get("tagName"));
}
[AllowAnonymous]
[HttpGet("checktag")]
public async Task<IActionResult> CheckTag()
{
var deploy = Appsettings.Get("deploy");
if(string.IsNullOrWhiteSpace(deploy))
{
return await GetDockerTagVersions();
}
else
{
if(deploy== "fn")//飞牛
{
return ApiResult.Success(new List<string> { "beta_"+Appsettings.Get("fnVersion") });
}
else
{
return await GetDockerTagVersions();
}
}
}
private static async Task<IActionResult> GetDockerTagVersions()
{
var data = await DouyinHttpHelper.GetTenImage(Appsettings.Get("tagName"));
if (data.IsSuccessStatusCode)
{
var content = await data.Content.ReadAsStringAsync();
var tagData = JsonConvert.DeserializeObject<DouyinApiResponse<List<string>>>(content);
if (tagData != null && tagData.Data != null && tagData.Data.Count > 0)
return ApiResult.Success(tagData.Data);
return ApiResult.Fail();
}
else
{
return ApiResult.Fail("请求失败");
}
}
///// <summary>
///// 上传音频文件接口
///// </summary>
///// <param name="file">要上传的音频文件</param>
///// <returns>上传结果</returns>
//[HttpPost("UploadAudio")]
//public IActionResult UploadAudio(IFormFile file)
//{
// // 1. 验证文件是否为空
// if (file == null || file.Length == 0)
// {
// return BadRequest(new { success = false, message = "请选择要上传的音频文件" });
// }
// try
// {
// // 2. 验证文件大小
// if (file.Length > _maxFileSize)
// {
// return BadRequest(new { success = false, message = $"文件大小超过限制(最大允许 {_maxFileSize / 1024 / 1024}MB" });
// }
// // 3. 获取文件扩展名并验证
// var fileExtension = Path.GetExtension(file.FileName).ToLower();
// if (!_allowedAudioExtensions.Contains(fileExtension))
// {
// return BadRequest(new
// {
// success = false,
// message = $"不支持的音频格式,仅允许:{string.Join(", ", _allowedAudioExtensions)}"
// });
// }
// // 4. 验证 MIME 类型(可选但推荐,防止扩展名伪造)
// var contentType = file.ContentType.ToLower();
// if (!_allowedAudioMimeTypes.Contains(contentType))
// {
// return BadRequest(new
// {
// success = false,
// message = "文件类型验证失败,请上传合法的音频文件"
// });
// }
// //先删除
// var uploadMp3 = Directory.GetFiles(Path.Combine(AppContext.BaseDirectory, "mp3"))
// .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != "silent_10")
// .FirstOrDefault();
// if (!string.IsNullOrWhiteSpace(uploadMp3) && System.IO.File.Exists(uploadMp3))
// {
// System.IO.File.Delete(uploadMp3);
// }
// // 5. 生成唯一文件名(避免重复)
// var uniqueFileName = $"dysync_default{fileExtension}";
// // 6. 定义文件保存路径(建议配置在 appsettings.json 中,这里简化处理)
// var uploadPath = Path.Combine(AppContext.BaseDirectory, "mp3");
// // 确保目录存在
// if (!Directory.Exists(uploadPath))
// {
// Directory.CreateDirectory(uploadPath);
// }
// // 7. 保存文件
// var filePath = Path.Combine(uploadPath, uniqueFileName);
// if (System.IO.File.Exists(filePath))
// {
// System.IO.File.Delete(filePath);
// }
// using (var stream = new FileStream(filePath, FileMode.Create))
// {
// file.CopyTo(stream);
// }
// // 8. 返回成功结果(可根据需求返回文件路径/URL 等)
// return ApiResult.Success(new { fileName = uniqueFileName, filePath });
// }
// catch (Exception ex)
// {
// // 捕获异常并返回错误信息
// return ApiResult.Fail(ex.Message);
// }
//}
//[AllowAnonymous]
//[HttpGet("defaudio")]
//public async Task<IActionResult> GetDefaultAudioUrl()
//{
// var uploadMp3 = Directory.GetFiles(Path.Combine(AppContext.BaseDirectory, "mp3"))
// .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != "silent_10")
// .FirstOrDefault();
// if (!string.IsNullOrWhiteSpace(uploadMp3) && System.IO.File.Exists(uploadMp3))
// {
// return File(System.IO.File.ReadAllBytes(uploadMp3), "application/octet-stream", Path.GetFileName(uploadMp3));
// }
// return ApiResult.Fail("未上传音频");
//}
}
}