Browse Source

更新

master
赵新宇 1 week ago
parent
commit
55237b5d91
  1. 24
      API/TaskManager.Entity/Entity.cs
  2. 44
      API/Wood.Admin.WebApi/Other/ServiceCollectionExtensions.cs
  3. 99
      API/Wood.Admin.WebApi/Startup.cs
  4. 4
      API/Wood.Service/Controllers/CheryRecurringJobOutPageController.cs
  5. 192
      API/Wood.Service/Controllers/LogController.cs
  6. 411
      API/Wood.Service/Controllers/LogService.cs
  7. 190
      API/Wood.Service/Controllers/TaskConifgureController.cs

24
API/TaskManager.Entity/Entity.cs

@ -570,7 +570,7 @@ namespace TaskManager.Entity
/// 零件名称
/// </summary>
[JsonPropertyName("materialDescription")]
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; } = string.Empty;
@ -767,7 +767,7 @@ namespace TaskManager.Entity
/// 字符串长度限制:50 字节
/// </summary>
[ExporterHeader(DisplayName = "零件名称")]
[StringLength(50)]
[StringLength(100)]
public string? MaterialDescription { get; set; } = string.Empty;
/// <summary>
@ -1029,7 +1029,7 @@ namespace TaskManager.Entity
/// 零件名称
/// </summary>
[ExporterHeader(DisplayName = "零件名称")]
[MaxLength(50)]
[MaxLength(100)]
public string? MaterialDescription { get; set; } = "";
/// <summary>
@ -1166,7 +1166,7 @@ namespace TaskManager.Entity
/// <summary>
/// 物料描述
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "物料描述")]
public string? MaterialDescription { get; set; }
@ -1342,7 +1342,7 @@ namespace TaskManager.Entity
/// <summary>
/// 物料描述
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "物料描述")]
public string? MaterialDescription { get; set; }
@ -1447,7 +1447,7 @@ namespace TaskManager.Entity
/// <summary>
/// 物料描述
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "物料描述")]
public string? MaterialDescription { get; set; }
@ -1559,7 +1559,7 @@ namespace TaskManager.Entity
/// <summary>
/// 物料描述
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "物料描述")]
public string? MaterialDescription { get; set; }
@ -1695,7 +1695,7 @@ namespace TaskManager.Entity
/// <summary>
/// 零件名称
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; }
@ -1858,7 +1858,7 @@ namespace TaskManager.Entity
/// <summary>
/// 零件名称
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; }
@ -1971,7 +1971,7 @@ namespace TaskManager.Entity
/// <summary>
/// 零件名称
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; }
@ -2098,7 +2098,7 @@ namespace TaskManager.Entity
/// <summary>
/// 零件名称
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; }
@ -2250,7 +2250,7 @@ namespace TaskManager.Entity
/// <summary>
/// 零件名称
/// </summary>
[MaxLength(50)]
[MaxLength(100)]
[ExporterHeader(DisplayName = "零件名称")]
public string? MaterialDescription { get; set; }

44
API/Wood.Admin.WebApi/Other/ServiceCollectionExtensions.cs

@ -105,28 +105,28 @@ namespace Wood.Admin.WebApi
#endregion
#region autoJob 初始化
public static void UseAutoJob(this IApplicationBuilder app)
{
Task.Run(async () =>
{
if (GlobalContext.SystemConfig!.RunAutoJob)
{
//延迟 5s
await Task.Delay(5 * 1000);
try
{
AutoJobCenter jobCenter = new AutoJobCenter();
jobCenter.ScanJob();
await jobCenter.AddScheduleJob();
}
catch (Exception ex)
{
Log.Error(ex, "初始化自动job失败!");
}
}
});
}
//public static void UseAutoJob(this IApplicationBuilder app)
//{
// Task.Run(async () =>
// {
// if (GlobalContext.SystemConfig!.RunAutoJob)
// {
// //延迟 5s
// await Task.Delay(5 * 1000);
// try
// {
// AutoJobCenter jobCenter = new AutoJobCenter();
// jobCenter.ScanJob();
// await jobCenter.AddScheduleJob();
// }
// catch (Exception ex)
// {
// Log.Error(ex, "初始化自动job失败!");
// }
// }
// });
//}
#endregion
#region sqlsugar初始化

99
API/Wood.Admin.WebApi/Startup.cs

@ -11,15 +11,20 @@ using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;
using Quartz;
using SixLabors.ImageSharp.Drawing;
using Swashbuckle.AspNetCore.Filters;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using TaskManager.Controllers;
using TaskManager.Entity;
using TaskManager.EntityFramework;
@ -28,7 +33,9 @@ using TaskManager.EntityFramework.Repository;
using Wood.Admin.WebApi.Filter;
using Wood.Admin.WebApi.Middleware;
using Wood.Data.Repository;
using Wood.Service.Controllers;
using Wood.Service.Controllers.RegistService;
using Wood.Service.SystemManage;
using Wood.Util;
namespace Wood.Admin.WebApi
@ -67,26 +74,8 @@ namespace Wood.Admin.WebApi
GlobalContext.JwtConfig = Configuration.GetSection("JwtConfig").Get<JwtConfig>()!;
GlobalContext.Services = services;
GlobalContext.Configuration = Configuration;
//// 扫描当前程序集
//var assembly = Assembly.GetExecutingAssembly();
//// 方法1:按约定注册服务
//services.AddServicesByConvention(assembly);
//// 方法2:注册所有实现了IRepository接口的类
//services.AddImplementationsOf<IRepository>(assembly);
//// 方法3:注册特定命名空间下的所有服务
//services.Scan(scan => scan
// .FromAssemblyOf<Startup>()
// .AddClasses(classes => classes.InNamespace("YourProject.Services"))
// .AsImplementedInterfaces()
// .WithScopedLifetime());
@ -97,51 +86,7 @@ namespace Wood.Admin.WebApi
services.AddSqlSugar(Configuration);
services.AddHttpClient();
//services.AddScoped<LogController>();
//services.AddScoped<TaskConifgureController>();
//// 注册所有需要通过 GetRequiredService 获取的服务
//// 1. 整车月度生产计划相关
//services.AddScoped<SupplierProPlaningService>();
//// 2. M+6月物料需求计划相关
//services.AddScoped<CherySupplierMrpMonthService>();
//// 3. 日物料需求计划相关
//services.AddScoped<CherySupplierMrpDataService>();
//// 4. 计划协议相关
//services.AddScoped<CherySupplierSaWeekService>();
//// 5. 采购订单相关
//services.AddScoped<CherySupplierPoService>();
//// 6. 过焊装未过总装相关
//services.AddScoped<CherySupplierPorHSCHEDULService>();
//// 7. 过涂装未过总装相关
//services.AddScoped<CherySupplierProTSCHEDULService>(); // 注意类型名是否包含大小写问题(如驼峰命名)
//// 8. 排序供货相关
//services.AddScoped<CherySupplierProCSCHEDULService>();
//// 9. 看板配送单相关
//services.AddScoped<CherySupplierDelStateService>();
//// 10. 退货单相关
//services.AddScoped<CherySupplierReturnService>();
//// 11. 奇瑞RDC共享库存相关
//services.AddScoped<SupplierInvDataService>();
//// 12. 日MRP预警推移相关
//services.AddScoped<CherySupplierMrpWarningService>();
//// 13. 供应商共享库存相关
//services.AddScoped<CherySupplierSinvDataService>();
// 14. 风险确认相关服务(如果类型名正确)
@ -296,7 +241,7 @@ namespace Wood.Admin.WebApi
{
foreach (var item in assembly)
{
var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{item.GetName().Name}.xml");
var xmlPath = System.IO.Path.Combine(AppContext.BaseDirectory, $"{item.GetName().Name}.xml");
if (File.Exists(xmlPath))
options.IncludeXmlComments(xmlPath, true);
@ -352,22 +297,26 @@ namespace Wood.Admin.WebApi
#endregion
});
//services.AddControllers();
//var s = services.BuildServiceProvider().GetRequiredService<TaskConifgureController>();
//services.AddSingleton<BackgroundService>();
//services.AddHostedService<BackgroundService>();
services.AddSingleton<LogController>();
services.AddHostedService<LogConsumerService>();
//s.TaskAllAsync("2025-05-29");
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{

4
API/Wood.Service/Controllers/CheryRecurringJobOutPageController.cs

@ -115,6 +115,7 @@ namespace TaskManager.Controllers
T entity = new T();
entity.InjectFrom(itm);
entity.CreationTime = DateTime.Now;
entity.RequestDate = date;
pagefirstList.Add(entity);
allData.Add(itm);
}
@ -171,6 +172,7 @@ namespace TaskManager.Controllers
T entity = new T();
entity.InjectFrom(itm);
entity.CreationTime = DateTime.Now;
entity.RequestDate = date;
pageList.Add(entity);
allData.Add(itm);
}
@ -244,6 +246,7 @@ namespace TaskManager.Controllers
entity.InjectFrom(itm);
entity.CreationTime = DateTime.Now;
pagefirstList.Add(entity);
entity.RequestDate = date;
allData.Add(itm);
}
@ -294,6 +297,7 @@ namespace TaskManager.Controllers
T entity = new T();
entity.InjectFrom(itm);
entity.CreationTime = DateTime.Now;
entity.RequestDate = date;
pageList.Add(entity);
allData.Add(itm);
}

192
API/Wood.Service/Controllers/LogController.cs

@ -20,44 +20,61 @@ using Wood.Service.Controllers;
namespace TaskManager.Controllers
{
public class LogController:NormalBaseController<TaskLog>
using System;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
public class LogController
{
public LogController(JobDbContext context, IServiceProvider builder, IConfiguration configuration, IRepository<TaskLog> repository) : base(context, builder, configuration, repository)
private readonly Channel<TaskLog> _logChannel;
public LogController(int bufferSize = 1000)
{
// 创建有界通道,设置缓冲区大小
var options = new BoundedChannelOptions(bufferSize)
{
FullMode = BoundedChannelFullMode.Wait
};
_logChannel = Channel.CreateBounded<TaskLog>(options);
}
public async Task<List<TaskLog>> GetAll()
public void EnqueueLog(TaskLog log)
{
var log = await _context.TaskLogs.ToListAsync();
return log;
_logChannel.Writer.TryWrite(log);
}
//[HttpGet("AddError")]
//public async Task<bool> AddError(string message,string taskname)
//private readonly LogBackgroundService _logService;
//public LogController(JobDbContext context, IServiceProvider builder, IConfiguration configuration, IRepository<TaskLog> repository, LogBackgroundService logService) : base(context, builder, configuration, repository)
//{
// _context.TaskLogs.Add(new TaskLog() { Info = message, Type = "错误",TaskName=taskname ,CreationTime=DateTime.Now});
// var result =await _context.SaveChangesAsync();
// if (result > 0)
// {
// return true;
// }
// return false;
// _logService = logService;
//}
//[HttpGet("AddInfo")]
//public async Task<bool> AddInfo(string message, string taskname)
//[HttpGet]
//public async Task<List<TaskLog>> GetAll()
//{
// _context.TaskLogs.Add(new TaskLog() { Info = message, Type = "记录", TaskName = taskname, CreationTime = DateTime.Now });
// var result = await _context.SaveChangesAsync();
// if (result > 0)
// {
// return true;
// }
// return false;
// var log = await _context.TaskLogs.ToListAsync();
// return log;
//}
public ChannelReader<TaskLog> GetLogReader()
{
return _logChannel.Reader;
}
[HttpGet("AddError")]
[NonAction]
//[HttpGet("AddError")]
public async Task<bool> AddError(string message, string taskname, Guid taskid, string version)
{
var log = new TaskLog
@ -69,14 +86,14 @@ namespace TaskManager.Controllers
TaskId = taskid,
Version = version?.ToString()
};
_context.TaskLogs.Add(log);
var result = await _context.SaveChangesAsync();
EnqueueLog(log);
//_context.TaskLogs.Add(log);
//var result = await _context.SaveChangesAsync();
return true; // 日志已入队,视为成功
}
[HttpGet("AddInfo")]
[NonAction]
//[HttpGet("AddInfo")]
public async Task<bool> AddInfo(string message, string taskname, Guid taskid, string version)
{
var log = new TaskLog
@ -88,14 +105,15 @@ namespace TaskManager.Controllers
TaskId = taskid,
Version = version?.ToString()
};
_context.TaskLogs.Add(log);
var result = await _context.SaveChangesAsync();
EnqueueLog(log);
//_context.TaskLogs.Add(log);
//var result = await _context.SaveChangesAsync();
return true;
}
[HttpGet("AddPostRequest")]
public async Task<bool> AddPostRequest(string message, string taskname, Guid taskid, string version,string remark)
[NonAction]
//[HttpGet("AddPostRequest")]
public async Task<bool> AddPostRequest(string message, string taskname, Guid taskid, string version, string remark)
{
var log = new TaskLog
{
@ -105,14 +123,16 @@ namespace TaskManager.Controllers
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString(),
Remark = remark
Remark = remark
};
_context.TaskLogs.Add(log);
var result = await _context.SaveChangesAsync();
EnqueueLog(log);
//_context.TaskLogs.Add(log);
//var result = await _context.SaveChangesAsync();
return true;
}
[HttpGet("AddPostResponse")]
public async Task<bool> AddPostResponse(string message, string taskname, Guid taskid, string version,string remaek)
[NonAction]
//[HttpGet("AddPostResponse")]
public async Task<bool> AddPostResponse(string message, string taskname, Guid taskid, string version, string remaek)
{
var log = new TaskLog
{
@ -122,99 +142,15 @@ namespace TaskManager.Controllers
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString(),
Remark = remaek
Remark = remaek
};
_context.TaskLogs.Add(log);
var result = await _context.SaveChangesAsync();
EnqueueLog(log);
return true;
}
[HttpGet("AddInfoRemark")]
public async Task<bool> AddInfoRemark(string message, string taskname,string remark)
{
_context.TaskLogs.Add(new TaskLog() { Info = message, Type = "记录", TaskName = taskname, CreationTime = DateTime.Now,Remark=remark });
var result = await _context.SaveChangesAsync();
if (result > 0)
{
return true;
}
return false;
}
public async Task<FileStreamResult> Export([FromQuery] int pageNumber = 1,
[FromQuery] int pageSize = 10,
[FromQuery] string sortBy = "",
[FromQuery] bool isAscending = true,
[FromQuery] Dictionary<string, string> filters = null)
{
var pagingParams = new PagingParams
{
PageNumber = pageNumber,
PageSize = pageSize,
SortBy = sortBy,
IsAscending = isAscending,
Filters = filters
};
// 可以在这里构建表达式树过滤条件
Expression<Func<T, bool>> filter = null;
var pagedResult = await _repository.GetPagedAsync(null, pagingParams);
return await ExportFile<TaskLog>(pagedResult.Data, Guid.NewGuid().ToString() + ".xlsx");
}
protected async Task<FileStreamResult> ExportFile<T>(ICollection<T> dtos, string fileName) where T : class, new()
{
var excelExporter = HttpContext.RequestServices.GetRequiredService<IExcelExporter>();
var res = await excelExporter.ExportAsByteArray(dtos);
return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "_" + fileName };
}
}
/// 导出
/// </summary>
/// <param name="pageNumber">第几页</param>
/// <param name="pageSize">每页条数</param>
/// <param name="sortBy">排序列</param>
/// <param name="isAscending">是否升序</param>
/// <param name="filters">查询条件</param>
/// <returns></returns>
//private readonly IServiceProvider _serviceProvider;
//public LogController(IServiceProvider serviceProvider)
//{
// _serviceProvider = serviceProvider;
//}
//public async Task<IEnumerable<Logs>> GetLogs()
//{
// var dbcontext= _serviceProvider.GetRequiredService<JobDbContext>();
// var connection=dbcontext.Database.GetDbConnection();
// connection.Query<Logs>("select top 10 * from logs");
//}
}
}

411
API/Wood.Service/Controllers/LogService.cs

@ -1,239 +1,286 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Channels;
using System.Threading.Tasks;
using TaskManager.Entity;
using TaskManager.EntityFramework;
using Wood.Entity;
using Wood.Service.SystemManage;
namespace Wood.Service.Controllers
namespace TaskManager.Controllers
{
public class LogController1 : BackgroundService
public class LogConsumerService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly Channel<TaskLog> _logChannel;
private readonly ChannelReader<TaskLog> _logReader;
private readonly ILogger<LogConsumerService> _logger;
private const int BatchSize = 100; // 批量写入大小
private readonly string _logDirectory;
private readonly IServiceProvider _serviceProvider;
public LogController1(
IServiceProvider serviceProvider,
IConfiguration configuration)
public LogConsumerService(
LogController logService,
ILogger<LogConsumerService> logger, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_logDirectory = configuration["Logging:Directory"] ??
Path.Combine(Directory.GetCurrentDirectory(), "Logs");
_logReader = logService.GetLogReader();
_logger = logger;
_serviceProvider = serviceProvider; ;
_logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomLogs"); // 使用更安全的路径获取方式
EnsureDirectoryExists(_logDirectory);
_logChannel = Channel.CreateUnbounded<TaskLog>();
}
}
public void EnqueueLog(TaskLog logMessage)
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// 设置日志路径并写入文件
logMessage.Path= WriteLogToFile(logMessage);
_logger.LogInformation("日志消费服务已启动");
// 将日志加入处理队列
_logChannel.Writer.TryWrite(logMessage);
// 批量处理日志,减少数据库写入次数
while (!stoppingToken.IsCancellationRequested &&
await _logReader.WaitToReadAsync(stoppingToken))
{
try
{
var logs = new List<TaskLog>();
int count = 0;
// 读取一批日志
while (_logReader.TryRead(out var log) && count < BatchSize)
{
logs.Add(log);
count++;
}
if (logs.Any())
{
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<JobDbContext>();
List<TaskLog> logsToSave = new List<TaskLog>();
foreach (var log in logs)
{
if (!string.IsNullOrEmpty(log.Remark))
{
log.Path = WriteLogToFile(log.Remark);
}
log.Remark = string.Empty;
logsToSave.Add(log);
}
await db.TaskLogs.AddRangeAsync(logsToSave, stoppingToken);
await db.SaveChangesAsync(stoppingToken);
_logger.LogInformation($"已写入 {logs.Count} 条日志");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "日志写入数据库失败");
// 错误处理:可记录到临时文件或重试
await Task.Delay(1000, stoppingToken); // 短暂延迟后重试
}
}
}
private string WriteLogToFile(TaskLog logMessage)
public override async Task StopAsync(CancellationToken stoppingToken)
{
// 获取今天的日期目录
string todayDirectory = Path.Combine(_logDirectory, DateTime.Now.ToString("yyyy-MM-dd"));
_logger.LogInformation("日志消费服务正在停止");
// 处理剩余日志
await base.StopAsync(stoppingToken);
}
private void EnsureDirectoryExists(string directoryPath)
{
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
}
// 修改后的日志写入方法
private string WriteLogToFile(string jsonContent)
{
//if string.IsNullOrEmpty(logMessage.RawRemark)) return null; // 必须提供JSON数据
// 确保目录存在
EnsureDirectoryExists(todayDirectory);
// 创建日期目录
string dateDirectory = DateTime.Now.ToString("yyyy-MM-dd");
string fullDatePath = Path.Combine(_logDirectory, dateDirectory);
EnsureDirectoryExists(fullDatePath);
// 创建或追加到日志文件
string logFilePath = Path.Combine(todayDirectory, "application.log");
// 生成唯一文件名(时间戳+随机数)
string fileName = $"log_{DateTime.Now.Ticks}_{Random.Shared.Next(1000, 9999)}.json";
string fullPath = Path.Combine(fullDatePath, fileName);
try
{
// 写入日志内容到文件
File.AppendAllText(logFilePath,
$"[{logMessage.CreationTime:yyyy-MM-dd HH:mm:ss}] [{logMessage.Type}] {logMessage.Info}{Environment.NewLine}");
// 返回相对路径(从日志根目录开始)
return Path.GetRelativePath(_logDirectory, logFilePath);
// 写入文件(使用UTF-8无BOM格式)
File.WriteAllText(fullPath, jsonContent, new UTF8Encoding(false));
// 存储相对路径(从日志根目录开始,使用正斜杠兼容API)
return Path.Combine(dateDirectory, fileName).Replace('\\', '/');
}
catch (Exception ex)
{
// 记录日志写入失败的错误
Console.WriteLine($"Error writing log to file: {ex.Message}");
return null;
}
}
Console.WriteLine($"JSON文件写入失败:{ex.Message}");
private void EnsureDirectoryExists(string directoryPath)
{
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
return null;
}
}
//[HttpGet("AddError")]
//public async Task<bool> AddError(string message, string taskname, Guid taskid, Version version)
//{
// var log = new TaskLog
// {
// Info = message,
// Type = "错误",
// TaskName = taskname,
// CreationTime = DateTime.Now,
// TaskId = taskid,
// Version = version?.ToString()
// };
// EnqueueLog(log);
// return true; // 日志已入队,视为成功
//}
//[HttpGet("AddInfo")]
//public async Task<bool> AddInfo(string message, string taskname, Guid taskid, Version version)
//{
// var log = new TaskLog
// {
// Info = message,
// Type = "错误",
// TaskName = taskname,
// CreationTime = DateTime.Now,
// TaskId = taskid,
// Version = version?.ToString()
// };
// EnqueueLog(log);
// return true;
//}
//[HttpGet("AddInfoRemark")]
//public async Task<bool> AddInfoRemark(string message, string taskname, string remark)
//{
// var log = new TaskLog
// {
// Info = message,
// Type = "记录",
// TaskName = taskname,
// CreationTime = DateTime.Now,
// Remark = remark
// };
// EnqueueLog(log);
// return true;
//}
[HttpGet("AddError")]
public async Task<bool> AddError(string message, string taskname, Guid taskid, string version)
{
var log = new TaskLog
{
Info = message,
Type = "错误",
TaskName = taskname,
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString()
};
EnqueueLog(log);
return true; // 日志已入队,视为成功
}
}
[HttpGet("AddInfo")]
public async Task<bool> AddInfo(string message, string taskname, Guid taskid, string version)
{
var log = new TaskLog
{
Info = message,
Type = "信息",
TaskName = taskname,
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString()
};
EnqueueLog(log);
return true;
}
[HttpGet("AddPostRequest")]
public async Task<bool> AddPostRequest(string message, string taskname, Guid taskid, string version, string remark)
{
var log = new TaskLog
{
Info = message,
Type = "请求",
TaskName = taskname,
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString(),
Remark = remark
};
EnqueueLog(log);
return true;
}
[HttpGet("AddPostResponse")]
public async Task<bool> AddPostResponse(string message, string taskname, Guid taskid, string version, string remaek)
{
var log = new TaskLog
{
Info = message,
Type = "应答",
TaskName = taskname,
CreationTime = DateTime.Now,
TaskId = taskid,
Version = version?.ToString(),
Remark = remaek
};
EnqueueLog(log);
return true;
}
// 后台服务
//public class LogBackgroundService : BackgroundService
//{
// private readonly Channel<TaskLog> _logChannel;
// private readonly IServiceProvider _serviceProvider;
// private readonly string _logDirectory;
// public LogBackgroundService(IServiceProvider serviceProvider, IConfiguration configuration)
// {
// Console.WriteLine("LogService 初始化");
// _serviceProvider = serviceProvider;
// _logDirectory = configuration["Logging:Directory"] ??
// Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomLogs"); // 使用更安全的路径获取方式
// EnsureDirectoryExists(_logDirectory);
// _logChannel = Channel.CreateUnbounded<TaskLog>();
// }
// public void EnqueueLog(TaskLog log)
// {
// _logChannel.Writer.TryWrite(log);
// }
// public override async Task StartAsync(CancellationToken cancellationToken)
// {
// // 服务启动前的准备工作
// // _logger.LogInformation("Worker starting up...");
// // 调用基类方法
// await base.StartAsync(cancellationToken);
// }
// public override async Task StopAsync(CancellationToken cancellationToken)
// {
// // 服务停止前的清理工作
// //_logger.LogInformation("Worker shutting down...");
// // 调用基类方法
// await base.StopAsync(cancellationToken);
// }
// public override void Dispose()
// {
// // 资源释放
// // _logger.LogInformation("Worker disposing resources");
// base.Dispose();
// }
// protected override async Task ExecuteAsync(CancellationToken stoppingToken)
// {
// Console.WriteLine("LogService 开始执行后台任务");
// using PeriodicTimer timer = new(TimeSpan.FromSeconds(10));
// // 主循环 - 使用 PeriodicTimer 等待下一个触发时间
// while (await timer.WaitForNextTickAsync(stoppingToken))
// {
// await foreach (var log in _logChannel.Reader.ReadAllAsync(stoppingToken))
// {
// try
// {
// if (!string.IsNullOrEmpty(log.Remark))
// {
// log.Path = WriteLogToFile(log.Remark);
// }
// log.Remark = string.Empty;
// using var scope = _serviceProvider.CreateScope();
// var db = scope.ServiceProvider.GetRequiredService<JobDbContext>();
// await db.TaskLogs.AddAsync(log, stoppingToken);
// await db.SaveChangesAsync(stoppingToken);
// Console.WriteLine($"日志已保存: {log.Info}");
// }
// catch (Exception ex)
// {
// Console.WriteLine($"日志处理失败: {ex.Message}");
// }
// }
// }
// Console.WriteLine("LogService 后台任务已停止");
// }
// private void EnsureDirectoryExists(string directoryPath)
// {
// if (!Directory.Exists(directoryPath))
// {
// Directory.CreateDirectory(directoryPath);
// }
// }
// // 修改后的日志写入方法
// private string WriteLogToFile(string jsonContent)
// {
// //if string.IsNullOrEmpty(logMessage.RawRemark)) return null; // 必须提供JSON数据
// // 创建日期目录
// string dateDirectory = DateTime.Now.ToString("yyyy-MM-dd");
// string fullDatePath = Path.Combine(_logDirectory, dateDirectory);
// EnsureDirectoryExists(fullDatePath);
// // 生成唯一文件名(时间戳+随机数)
// string fileName = $"log_{DateTime.Now.Ticks}_{Random.Shared.Next(1000, 9999)}.json";
// string fullPath = Path.Combine(fullDatePath, fileName);
// try
// {
// // 写入文件(使用UTF-8无BOM格式)
// File.WriteAllText(fullPath, jsonContent, new UTF8Encoding(false));
// // 存储相对路径(从日志根目录开始,使用正斜杠兼容API)
// return Path.Combine(dateDirectory, fileName).Replace('\\', '/');
// }
// catch (Exception ex)
// {
// Console.WriteLine($"JSON文件写入失败:{ex.Message}");
// return null;
// }
// }
//}
}
// 其他方法保持不变...
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await foreach (var logMessage in _logChannel.Reader.ReadAllAsync(stoppingToken))
{
// 使用IServiceScopeFactory创建独立的作用域
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<JobDbContext>();
try
{
dbContext.TaskLogs.Add(logMessage);
await dbContext.SaveChangesAsync(stoppingToken);
}
catch (Exception ex)
{
Console.WriteLine($"Error saving log: {ex.Message}");
}
}
}
}
}

190
API/Wood.Service/Controllers/TaskConifgureController.cs

@ -68,185 +68,7 @@ namespace TaskManager.Controllers
}
/// <summary>
///// <summary>
///// 执行铁定任务
///// </summary>
///// <param name="taskName"></param>
///// <returns></returns>
//[NonAction]
//public async Task testTask(string taskName)
//{
// var first = await _context.TaskConifgure.FirstOrDefaultAsync(p => p.TaskName == taskName);
// var url = first.Url;
// var path = first.Api;
// var controller = _builder.GetRequiredService<SupplierProPlaningService>();
// await controller.TestAsync(url, path, taskName, "2025-04-21");
//}
//[NonAction]
//public async Task TaskAllAsync(string date)
//{
// var tasks = _context.TaskConifgure.Where(p => p.IsAuto == true && !string.IsNullOrEmpty(p.Corn)
// && !string.IsNullOrEmpty(p.Api) && !string.IsNullOrEmpty(p.Url)).ToList();
// foreach (var task in tasks)
// {
// try
// {
// var url = task.Url;
// var path = task.Api;
// var taskname = task.TaskName;
// switch (task.TaskName)
// {
// //case "整车月度生产计划1":
// // // 添加的代码块
// // var controller1 = _builder.GetRequiredService<SupplierProPlaningService>();
// // await controller1.TestAsync(url, path, taskname, "2025-05-29");
// // break;
// case "M+6月物料需求计划1":
// // 添加的代码块
// var controller2 = _builder.GetRequiredService<CherySupplierMrpMonthService>();
// await controller2.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "整车月度生产计划2":
// // 添加的代码块
// var controller3 = _builder.GetRequiredService<SupplierProPlaningService>();
// await controller3.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "M+6月物料需求计划2":
// // 添加的代码块
// var controller4 = _builder.GetRequiredService<CherySupplierMrpMonthService>();
// await controller4.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "日物料需求计划":
// // 添加的代码块
// var controller5 = _builder.GetRequiredService<CherySupplierMrpDataService>();
// await controller5.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "计划协议":
// // 添加的代码块
// var controller6 = _builder.GetRequiredService<CherySupplierSaWeekService>();
// await controller6.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "采购订单":
// // 添加的代码块
// var controller7 = _builder.GetRequiredService<CherySupplierPoService>();
// await controller7.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "过焊装未过总装":
// // 添加的代码块
// var controller8 = _builder.GetRequiredService<CherySupplierPorHSCHEDULService>();
// await controller8.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "过涂装未过总装":
// // 添加的代码块
// var controller9 = _builder.GetRequiredService<CherySupplierProTSCHEDULService>();
// await controller9.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "排序供货":
// // 添加的代码块
// var controller10 = _builder.GetRequiredService<CherySupplierProCSCHEDULService>();
// await controller10.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "看板配送单":
// // 添加的代码块
// var controller11 = _builder.GetRequiredService<CherySupplierDelStateService>();
// await controller11.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "退货单":
// // 添加的代码块
// var controller12 = _builder.GetRequiredService<CherySupplierReturnService>();
// await controller12.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "奇瑞RDC共享库存":
// // 添加的代码块
// var controller13 = _builder.GetRequiredService<SupplierInvDataService>();
// await controller13.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "日MRP状态监控":
// // 添加的代码块
// var controller14 = _builder.GetRequiredService<CherySupplierMrpDataService>();
// await controller14.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "日MRP预警推移":
// // 添加的代码块
// var controller15 = _builder.GetRequiredService<CherySupplierMrpWarningService>();
// await controller15.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "供应商共享库存-上午":
// // 添加的代码块
// var controller19 = _builder.GetRequiredService<CherySupplierSinvDataService>();
// await controller19.TestAsync(url, path, taskname, "2025-05-29");
// break;
// case "供应商共享库存-晚上":
// // 添加的代码块
// var controller20 = _builder.GetRequiredService<CherySupplierSinvDataService>();
// await controller20.TestAsync(url, path, taskname, "2025-05-29");
// break;
// }
// }
// catch
// {
// }
// }
//}
/// <summary>
/// 设置任务是否自动执行
@ -306,6 +128,16 @@ namespace TaskManager.Controllers
public async Task RefreshTaskConfig()
{
//RecurringJob.AddOrUpdate<LogBackgroundService>(
// "日志定时任务",
// x => x.ExecuteAsync(),
// "*/10 * * * * *",
// TimeZoneInfo.Local
// );
// 从数据库加载所有任务配置
var tasks = _context.TaskConifgure.Where(p => p.IsAuto == true && !string.IsNullOrEmpty(p.Corn)

Loading…
Cancel
Save