Bläddra i källkod

任务分配新增日志、及部分调整

Lyyyi 1 dag sedan
förälder
incheckning
f8769840c2

+ 1 - 1
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -24,7 +24,6 @@ using OASystem.API.OAMethodLib.Hub.HubClients;
 using OASystem.API.OAMethodLib.Hub.Hubs;
 using OASystem.API.OAMethodLib.JuHeAPI;
 using OASystem.API.OAMethodLib.KiMiApi;
-using OASystem.API.OAMethodLib.Logging;
 using OASystem.API.OAMethodLib.QiYeWeChatAPI.AppNotice;
 using OASystem.Domain.AesEncryption;
 using OASystem.Domain.Attributes;
@@ -43,6 +42,7 @@ using OASystem.Domain.ViewModels.Groups;
 using OASystem.Domain.ViewModels.JuHeExchangeRate;
 using OASystem.Domain.ViewModels.OCR;
 using OASystem.Domain.ViewModels.SmallFun;
+using OASystem.Infrastructure.Logging;
 using OASystem.Infrastructure.Repositories.CRM;
 using OASystem.Infrastructure.Repositories.Financial;
 using OASystem.Infrastructure.Repositories.Groups;

+ 2 - 1
OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs

@@ -1113,6 +1113,7 @@ From
       u.CnName As CreateUserName,
       ta.CreateTime,
       ta.Remark,
+      ta.OverTime,
       (
         SELECT
           STUFF(
@@ -1178,7 +1179,7 @@ WHERE
                 //设置已知晓权限
                 (bool havePerm, string msg3) = _taskAllocationRep.TaskHavePerm(item.Id, dto.UserId);
                 item.TaskHavePerm = havePerm;
-                //设置详情权限
+                //设置详情权限
                 item.TaskDetailsPerm = _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
                     .Where(it => it.IsDel == 0 && it.TAId == item.Id && (it.UserId == dto.UserId || it.CreateUserId == dto.UserId))
                     .Any();

+ 0 - 22
OASystem/OASystem.Api/OAMethodLib/Logging/ITextFileLogger.cs

@@ -1,22 +0,0 @@
-namespace OASystem.API.OAMethodLib.Logging
-{
-    /// <summary>
-    /// 出入境费用文本日志接口
-    /// </summary>
-    public interface ITextFileLogger
-    {
-        void LogInformation(string message, params object[] args);
-        void LogWarning(string message, params object[] args);
-        void LogError(Exception ex, string message, params object[] args);
-    }
-
-    /// <summary>
-    /// 团组不走操作日志接口
-    /// </summary>
-    public interface IGroupTextFileLogger
-    {
-        void LogInformation(string message, params object[] args);
-        void LogWarning(string message, params object[] args);
-        void LogError(Exception ex, string message, params object[] args);
-    }
-}

+ 1 - 1
OASystem/OASystem.Api/OAMethodLib/QiYeWeChatAPI/AppNotice/Library.cs

@@ -7,7 +7,7 @@ using OASystem.Domain.ViewModels.Groups;
 using OASystem.Domain.ViewModels.QiYeWeChat;
 using OASystem.Infrastructure.Repositories.Groups;
 using OASystem.Domain.Entities.WorkOrder;
-using OASystem.API.OAMethodLib.Logging;
+using OASystem.Infrastructure.Logging;
 
 namespace OASystem.API.OAMethodLib.QiYeWeChatAPI.AppNotice
 {

+ 28 - 4
OASystem/OASystem.Api/Program.cs

@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.ResponseCompression;
 using Microsoft.AspNetCore.Server.Kestrel.Core;
 using Microsoft.Extensions.DependencyInjection.Extensions;
-using Microsoft.IdentityModel.Tokens;
 using OASystem.API.Middlewares;
 using OASystem.API.OAMethodLib;
 using OASystem.API.OAMethodLib.AMapApi;
@@ -12,10 +11,10 @@ using OASystem.API.OAMethodLib.DeepSeekAPI;
 using OASystem.API.OAMethodLib.GenericSearch;
 using OASystem.API.OAMethodLib.Hub.Hubs;
 using OASystem.API.OAMethodLib.JuHeAPI;
-using OASystem.API.OAMethodLib.Logging;
 using OASystem.API.OAMethodLib.QiYeWeChatAPI;
 using OASystem.API.OAMethodLib.Quartz.Jobs;
 using OASystem.API.OAMethodLib.SignalR.HubService;
+using OASystem.Infrastructure.Logging;
 using Quartz;
 using Quartz.Impl;
 using Quartz.Spi;
@@ -216,7 +215,7 @@ builder.Services.AddScoped(options =>
             //获取无参数化SQL 影响性能只适合调试
             //UtilMethods.GetSqlString(DbType.SqlServer, sql, pars);
 
-           
+
             if (pars != null || pars.Length > 0)
             {
                 Console.WriteLine("============== 完整 SQL ==============");
@@ -236,7 +235,7 @@ builder.Services.AddScoped(options =>
                         };
                         resultSql = resultSql.Replace(param.ParameterName, formattedValue);
                     }
-                    
+
                 }
                 Console.WriteLine(resultSql);
                 Console.WriteLine("=====================================");
@@ -442,11 +441,36 @@ var groupStepOP_TextLogger = new LoggerConfiguration()
 
 #endregion
 
+#region 任务分配操作 专用记录器
+
+// 指定磁盘绝对路径(示例:D盘的AppLogs文件夹)
+var taskLogDir = @"D:\OASystem\Logs\TaskAllocation";
+
+// 自动创建目录(如果不存在)
+try
+{
+    Directory.CreateDirectory(taskLogDir);
+    Log.Information($"日志目录已创建/确认存在: {taskLogDir}");
+}
+catch (Exception ex)
+{
+    Log.Fatal($"无法创建日志目录 {taskLogDir}: {ex.Message}");
+    throw;
+}
+
+var task_TextLogger = new LoggerConfiguration()
+    .MinimumLevel.Information()
+    .WriteTo.File(Path.Combine(taskLogDir, "text-records-.txt"), rollingInterval: RollingInterval.Month)
+    .CreateLogger();
+
+#endregion
+
 // 配置Serilog为Log;
 builder.Host.UseSerilog();
 
 builder.Services.AddSingleton<ITextFileLogger>(new TextFileLogger(eec_TextLogger));
 builder.Services.AddSingleton<IGroupTextFileLogger>(new GroupTextFileLogger(groupStepOP_TextLogger));
+builder.Services.AddSingleton<ITaskTextFileLogger>(new TaskTextFileLogger(task_TextLogger));
 #endregion
 
 #region 引入注册Autofac Module

+ 2 - 0
OASystem/OASystem.Domain/ViewModels/PersonnelModule/TaskAllocationView.cs

@@ -271,6 +271,8 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
         public List<TaskUserDetailsView>? UserTaskInfos { get; set; }
 
         public string Remark { get; set; }
+
+        public int TaskType { get; set; }
     }
 
 

+ 31 - 0
OASystem/OASystem.Infrastructure/Logging/ITextFileLogger.cs

@@ -0,0 +1,31 @@
+namespace OASystem.Infrastructure.Logging
+{
+
+    public interface IBaseTextFileLogger
+    {
+        void LogInformation(string message, params object[] args);
+        void LogWarning(string message, params object[] args);
+        void LogError(Exception ex, string message, params object[] args);
+    }
+
+    /// <summary>
+    /// 出入境费用文本日志接口
+    /// </summary>
+    public interface ITextFileLogger:IBaseTextFileLogger
+    {
+    }
+
+    /// <summary>
+    /// 团组步骤操作日志接口
+    /// </summary>
+    public interface IGroupTextFileLogger : IBaseTextFileLogger
+    {
+    }
+
+    /// <summary>
+    /// 团组步骤操作日志接口
+    /// </summary>
+    public interface ITaskTextFileLogger : IBaseTextFileLogger
+    {
+    }
+}

+ 21 - 2
OASystem/OASystem.Api/OAMethodLib/Logging/TextFileLogger.cs

@@ -1,7 +1,8 @@
 using ILogger = Serilog.ILogger;
 
-namespace OASystem.API.OAMethodLib.Logging
+namespace OASystem.Infrastructure.Logging
 {
+   
     /// <summary>
     /// 出入境费用明细日志记录
     /// </summary>
@@ -21,7 +22,7 @@ namespace OASystem.API.OAMethodLib.Logging
     }
 
     /// <summary>
-    /// 团组不走操作日志
+    /// 团组步骤操作日志
     /// </summary>
     public class GroupTextFileLogger : IGroupTextFileLogger
     {
@@ -37,4 +38,22 @@ namespace OASystem.API.OAMethodLib.Logging
         public void LogError(Exception ex, string message, params object[] args)
             => _logger.Error(ex, message, args);
     }
+
+    /// <summary>
+    /// 任务分配操作日志
+    /// </summary>
+    public class TaskTextFileLogger : ITaskTextFileLogger
+    {
+        private readonly ILogger _logger;
+        public TaskTextFileLogger(ILogger logger) => _logger = logger;
+
+        public void LogInformation(string message, params object[] args)
+            => _logger.Information(message, args);
+
+        public void LogWarning(string message, params object[] args)
+            => _logger.Warning(message, args);
+
+        public void LogError(Exception ex, string message, params object[] args)
+            => _logger.Error(ex, message, args);
+    }
 }

+ 281 - 31
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/TaskAllocationRepository.cs

@@ -8,6 +8,7 @@ using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.Entities.PersonnelModule;
 using OASystem.Domain.Entities.System;
 using OASystem.Domain.ViewModels.PersonnelModule;
+using OASystem.Infrastructure.Logging;
 using Org.BouncyCastle.Asn1.Tsp;
 using Org.BouncyCastle.Ocsp;
 using SqlSugar;
@@ -15,7 +16,9 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net.NetworkInformation;
+using System.Reflection;
 using System.Text;
+using System.Text.Json.Serialization;
 using System.Threading.Tasks;
 
 namespace OASystem.Infrastructure.Repositories.PersonnelModule
@@ -28,12 +31,14 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
     {
         private readonly IMapper _mapper;
         private Result _result;
+        private readonly ITaskTextFileLogger _taskTextFileLogger;
 
-        public TaskAllocationRepository(SqlSugarClient sqlSugar, IMapper mapper)
+        public TaskAllocationRepository(SqlSugarClient sqlSugar, IMapper mapper, ITaskTextFileLogger taskTextFileLogger)
             : base(sqlSugar)
         {
             _mapper = mapper;
             _result = new Result() { Code = -1, Msg = "操作失败!" };
+            _taskTextFileLogger = taskTextFileLogger;
         }
 
         /// <summary>
@@ -196,6 +201,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                         CreateTime = it.CreateTime,
                         TaskName = it.TaskName,
                         TaskContent = it.TaskContent,
+                        TaskType = it.TaskType,
                         TaskPriority = it.TaskPriority,
                         PredictBeginTime = it.PredictBeginTime,
                         PredictEndTime = it.PredictEndTime,
@@ -246,23 +252,23 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             if (taskInfo.CreateUserId != currentUserId)
                 return (false, "当前任务仅创建人可编辑!");
 
-            //// 定义结束状态集合
-            //var UneditableStatuses = new List<TaskEnum>
-            //{
-            //    TaskEnum.UnFinished,
-            //    TaskEnum.Finished,
-            //    TaskEnum.TaskStop
-            //};
-
-            //if (UneditableStatuses.Contains(taskInfo.Status))
-            //    return (false,
-            //        taskInfo.Status switch
-            //        {
-            //            TaskEnum.UnFinished => "当前任务状态为“未完成”结束状态,不可编辑!",
-            //            TaskEnum.Finished => "当前任务状态为“已完成”结束状态,不可编辑!",
-            //            TaskEnum.TaskStop => "当前任务状态为“任务终止”结束状态,不可编辑!",
-            //            _ => "当前任务状态不可编辑!"
-            //        });
+            // 定义结束状态集合
+            var UneditableStatuses = new List<TaskEnum>
+            {
+                TaskEnum.UnFinished,
+                TaskEnum.Finished,
+                TaskEnum.TaskStop
+            };
+
+            if (UneditableStatuses.Contains(taskInfo.Status))
+                return (false,
+                    taskInfo.Status switch
+                    {
+                        TaskEnum.UnFinished => "当前任务状态为“未完成”结束状态,不可编辑!",
+                        TaskEnum.Finished => "当前任务状态为“已完成”结束状态,不可编辑!",
+                        TaskEnum.TaskStop => "当前任务状态为“任务终止”结束状态,不可编辑!",
+                        _ => "当前任务状态不可编辑!"
+                    });
 
             return (true, string.Empty);
         }
@@ -407,6 +413,8 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
                 #endregion
 
+                var createUserName = _sqlSugar.Queryable<Sys_Users>().Where(x => x.Id == dto.UserId).First()?.CnName ?? "-";
+
                 if (dto.Id == 0) //添加
                 {
                     //// 1 按 任务名称 查询重
@@ -423,7 +431,8 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     if (addId < 1)
                     {
                         _sqlSugar.RollbackTran();
-                        _result.Msg = string.Format("任务发布失败!");
+                        _result.Msg = string.Format("任务发布失败!"); 
+                        _taskTextFileLogger.LogInformation("任务新增[失败],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
                         return _result;
                     }
 
@@ -438,17 +447,21 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     {
                         _sqlSugar.RollbackTran();
                         _result.Msg = string.Format("任务发布失败!");
+                        _taskTextFileLogger.LogInformation("任务新增[失败],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
                         return _result;
                     }
 
                     _result.Code = 0;
                     _result.Msg = "添加成功!";
+                    _taskTextFileLogger.LogInformation("任务新增[成功],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
+
                     _sqlSugar.CommitTran();
                 }
                 else if (dto.Id > 0) //修改
                 {
                     _sqlSugar.BeginTran();
 
+                   
                     #region 编辑验证 1. 仅创建者可以修改 
 
                     var taskInfo = await _sqlSugar
@@ -462,13 +475,27 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                         if (!isEdit)
                         {
                             _result.Msg = msg;
+                            _taskTextFileLogger.LogInformation("任务编辑[无操作权限],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
+
+                            _sqlSugar.RollbackTran();
                             return _result;
                         }
                     }
 
                     #endregion
-
-                    int updateStatus1 = await _sqlSugar.Updateable<Pm_TaskAllocation>(_TaskAllocation)
+                    var mainTaskInfoOld = new Pm_TaskAllocation() {
+                        DepId = taskInfo.DepId,
+                        DiId = taskInfo.DiId,
+                        TaskType = taskInfo.TaskType,
+                        TaskPriority = taskInfo.TaskPriority,
+                        TaskName = taskInfo.TaskName,
+                        TaskContent = taskInfo.TaskContent,
+                        PredictBeginTime = taskInfo.PredictBeginTime,
+                        PredictEndTime = taskInfo.PredictEndTime,
+                        IsIntoPerformance = taskInfo.IsIntoPerformance
+                    };
+
+                   int updateStatus1 = await _sqlSugar.Updateable<Pm_TaskAllocation>(_TaskAllocation)
                         .UpdateColumns(it => new
                         {
                             it.DepId,
@@ -487,6 +514,8 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     {
                         _sqlSugar.RollbackTran();
                         _result.Msg = string.Format("任务编辑失败!");
+                        _taskTextFileLogger.LogInformation("任务编辑[失败],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
+
                         return _result;
                     }
 
@@ -503,6 +532,8 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                         {
                             _sqlSugar.RollbackTran();
                             _result.Msg = string.Format("任务编辑失败!");
+                            _taskTextFileLogger.LogInformation("任务编辑[失败],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
+
                             return _result;
                         }
                     }
@@ -553,17 +584,36 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                                 {
                                     _sqlSugar.RollbackTran();
                                     _result.Msg = string.Format("任务编辑失败!");
+                                    _taskTextFileLogger.LogInformation("任务编辑[失败],任务名称:{TaskName},创建人:{CreateUserName}", _TaskAllocation.TaskName, createUserName);
+
                                     return _result;
                                 }
                             }
                         }
                     }
 
+                    var mainTaskInfoNew = new Pm_TaskAllocation()
+                    {
+                        DepId = _TaskAllocation.DepId,
+                        DiId = _TaskAllocation.DiId,
+                        TaskType = _TaskAllocation.TaskType,
+                        TaskPriority = _TaskAllocation.TaskPriority,
+                        TaskName = _TaskAllocation.TaskName,
+                        TaskContent = _TaskAllocation.TaskContent,
+                        PredictBeginTime = _TaskAllocation.PredictBeginTime,
+                        PredictEndTime = _TaskAllocation.PredictEndTime,
+                        IsIntoPerformance = _TaskAllocation.IsIntoPerformance
+                    }; ;
+
                     /*
                      * 发送消息
                      */
                     _result.Code = 0;
                     _result.Msg = "编辑成功!";
+                    var changeMsg = ChangeMsg(mainTaskInfoOld, mainTaskInfoNew);
+
+                    _taskTextFileLogger.LogInformation("任务完成设置[成功],任务名称:{TaskName},操作者:{OperatorName}{ChangeMsg}", _TaskAllocation.TaskName, createUserName, changeMsg);
+
                     _sqlSugar.CommitTran();
                 }
                 else _result.Msg = string.Format("请传入有效的Id参数!");
@@ -776,6 +826,8 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             }
 
             _sqlSugar.BeginTran();
+            var taskName = await _sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.IsDel == 0 && it.Id == id).Select(it => it.TaskName).FirstAsync();
+            var operatorName = await _sqlSugar.Queryable<Sys_Users>().Where(it => it.IsDel == 0 && it.Id == userId).Select(it => it.CnName).FirstAsync();
             var update1 = await _sqlSugar.Updateable<Pm_TaskRelevanceUser>()
                 .SetColumns(it => it.TaskStatus == TaskerEnum.HaveKnown)
                 .Where(it => it.TAId == id && it.UserId == userId)
@@ -783,6 +835,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             if (update1 < 1)
             {
                 _result.Msg = string.Format("操作失败!");
+
+                _taskTextFileLogger.LogInformation("任务知晓设置[失败],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
+
                 _sqlSugar.RollbackTran();
                 return _result;
             }
@@ -794,11 +849,13 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             if (update2 < 1)
             {
                 _result.Msg = string.Format("操作失败!");
+                _taskTextFileLogger.LogInformation("任务知晓设置[失败],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
                 _sqlSugar.RollbackTran();
                 return _result;
             }
 
             _result.Msg = string.Format("操作成功!");
+            _taskTextFileLogger.LogInformation("任务知晓设置[成功],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
             _result.Code = 0;
             _sqlSugar.CommitTran();
 
@@ -835,6 +892,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
             _sqlSugar.BeginTran();
 
+            var taskName =  _sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.IsDel == 0 && it.Id == id).Select(it => it.TaskName).First();
+            var operatorName =  _sqlSugar.Queryable<Sys_Users>().Where(it => it.IsDel == 0 && it.Id == userId).Select(it => it.CnName).First();
+
             try
             {
                 //状态验证
@@ -853,6 +913,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 if (subTaskInfo.CreateUserId != userId)
                 {
                     _result.Msg = string.Format("只有任务创建者可审批'已完成'状态!");
+                    _taskTextFileLogger.LogInformation("任务完成设置[尝试审批],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
                     return _result;
                 }
 
@@ -872,6 +933,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 if (subTaskUpd < 1)
                 {
                     _result.Msg = string.Format("操作失败!");
+                    _taskTextFileLogger.LogInformation("任务完成设置[失败],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
                     _sqlSugar.RollbackTran();
                     return _result;
                 }
@@ -884,33 +946,58 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     .Select(x => new
                     {
                         x.Id,
+                        x.UserId,
                         x.TaskStatus
                     })
                     .ToList();
 
+                var mainTaskInfoOld = _sqlSugar.Queryable<Pm_TaskAllocation>()
+                    .Where(x => x.Id == mainTaskId && x.IsDel == 0)
+                    .Select(x => new Pm_TaskAllocation
+                    {
+                        OverTime = x.OverTime,
+                        Status = x.Status,
+                        Remark = x.Remark
+                    })
+                    .First();
+                var mainTaskInfoNew = new Pm_TaskAllocation();
+
                 // 计算任务状态统计
                 int totalCount = allRelevanceTasks.Count;
 
-                // 已完成状态数量
-                int finishedCount = allRelevanceTasks.Count(x => x.TaskStatus == TaskerEnum.Finished);
-                // 未完成状态数量
-                int unfinishedCount = allRelevanceTasks.Count(x => x.TaskStatus == TaskerEnum.UnFinished);
+                // 已知晓状态数量
+                int haveCount = allRelevanceTasks.Count(x => x.TaskStatus >= TaskerEnum.HaveKnown);
+                // 未设置已知晓状态数量
+                int noHaveCount = allRelevanceTasks.Count(x => x.TaskStatus < TaskerEnum.HaveKnown);
+
+                if (noHaveCount > 0)
+                {
+                    //其他人未设置已知晓 不可设置 完成状态
+                    var userIds = allRelevanceTasks.Where(x => x.TaskStatus < TaskerEnum.HaveKnown).Select(x => x.UserId).ToList();
+                    var names = _sqlSugar.Queryable<Sys_Users>()
+                        .Where(x => userIds.Contains(x.Id))
+                        .Select(x => x.CnName)
+                        .ToList();
 
-                // 结束状态数量(已完成 + 未完成)
-                int endedCount = finishedCount + unfinishedCount;
+                    string userLabel = string.Join("、",names);
+
+                    _result.Msg = string.Format($"{userLabel} 未点击已知晓,不可设置任务完成。");
+                    _sqlSugar.RollbackTran();
+                    return _result;
+                }
 
                 // 判断是否所有子任务均处于结束状态 是 则更新主任务状态
-                bool allTasksInEndStatus = totalCount == endedCount;
+                bool allTasksInEndStatus = totalCount == haveCount;
                 if (allTasksInEndStatus)
                 {
                     TaskEnum newMainTaskStatus;
 
-                    if (unfinishedCount > 0)
+                    if (noHaveCount > 0)
                     {
                         // 存在未完成的子任务
                         newMainTaskStatus = TaskEnum.UnFinished;
                     }
-                    else if (finishedCount == totalCount)
+                    else if (haveCount == totalCount)
                     {
                         // 所有子任务都已完成
                         newMainTaskStatus = TaskEnum.Finished;
@@ -934,14 +1021,26 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     if (rowsAffected <= 0)
                     {
                         _result.Msg = string.Format("更新主任务状态失败!");
+                        _taskTextFileLogger.LogInformation("任务完成设置[失败],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
                         _sqlSugar.RollbackTran();
                         return _result;
                     }
-                }
+                    mainTaskInfoNew = new Pm_TaskAllocation
+                    {
+                        OverTime = overTime,
+                        Status = newMainTaskStatus,
+                        Remark = remark
+                    };
+                }else
 
                 #endregion
 
                 _result.Msg = string.Format("操作成功!");
+                var logMsgChange = new StringBuilder();
+
+                var changeMsg = ChangeMsg(mainTaskInfoOld, mainTaskInfoNew);
+
+                _taskTextFileLogger.LogInformation("任务完成设置[成功],任务名称:{TaskName},操作者:{OperatorName}{ChangeMsg}", taskName, operatorName, changeMsg);
                 _result.Code = 0;
                 _sqlSugar.CommitTran();
 
@@ -1189,6 +1288,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 return _result;
             }
             _sqlSugar.BeginTran();
+
+            var taskName = _sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.IsDel == 0 && it.Id == taskId).Select(it => it.TaskName).First();
+            var operatorName = _sqlSugar.Queryable<Sys_Users>().Where(it => it.IsDel == 0 && it.Id == userId).Select(it => it.CnName).First();
             var nowStrig = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             var taskUpdate = _sqlSugar.Updateable<Pm_TaskAllocation>()
                 .SetColumns(it => it.IsDel == 1)
@@ -1212,13 +1314,161 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             if (taskUpdate < 1)
             {
                 _result.Msg = "任务删除失败!";
+                _taskTextFileLogger.LogInformation("任务删除[失败],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
                 _sqlSugar.RollbackTran();
                 return _result;
             }
             _result.Msg = "操作成功!";
+            _taskTextFileLogger.LogInformation("任务删除[成功],任务名称:{TaskName},操作者:{OperatorName}", taskName, operatorName);
             _result.Code = 0;
             _sqlSugar.CommitTran();
             return _result;
         }
+
+        #region 操作日志
+
+        /// <summary>
+        /// 记录任务分配步骤值改变
+        /// </summary>
+        /// <param name="before">操作前的步骤数据实体</param>
+        /// <param name="after">操作后的步骤数据实体</param>
+        /// <returns>表示同步操作的任务</returns>
+        /// <remarks>此方法会自动比较前后数据的差异,生成变更字段列表和操作描述</remarks>
+        public string ChangeMsg(Pm_TaskAllocation before, Pm_TaskAllocation after)
+        {
+            // 合并基础排除字段和额外排除字段
+            var allExcludedFields = GetDefaultExcludedFields();
+            var changedFields = GetChangeDetails(before, after, allExcludedFields);
+
+            if (!changedFields.Any()) return "\r\n无内容变更\r\n\r\n";
+
+            return "\r\n值改变内容(只记录有变化的信息):\r\n" + string.Join("\r\n", changedFields.Select(x =>
+                $"{x.FieldName} ({x.BeforeValue} -> {x.AfterValue});")) + "\r\n";
+
+        }
+
+        /// <summary>
+        /// 获取字段变更详情
+        /// </summary>
+        /// <param name="before">变更前</param>
+        /// <param name="after">变更后</param>
+        /// <param name="exclFields">排除字段</param>
+        /// <returns>变更详情列表</returns>
+        private List<FieldChangeDetail> GetChangeDetails(Pm_TaskAllocation before, Pm_TaskAllocation after, List<string> exclFields = null)
+        {
+            var changeDetails = new List<FieldChangeDetail>();
+            var defaultExclFields = GetDefaultExcludedFields();
+
+            // 合并排除字段
+            var allExclFields = defaultExclFields;
+            if (exclFields != null && exclFields.Any())
+            {
+                allExclFields = defaultExclFields.Union(exclFields).ToList();
+            }
+
+            if (before == null || after == null) return changeDetails;
+
+            var properties = typeof(Pm_TaskAllocation).GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+            foreach (var prop in properties)
+            {
+                // 跳过排除的字段
+                if (allExclFields.Contains(prop.Name))
+                {
+                    continue;
+                }
+
+                var beforeValue = prop.GetValue(before);
+                var afterValue = prop.GetValue(after);
+
+                // 处理字符串类型的特殊比较(忽略前后空格)
+                if (prop.PropertyType == typeof(string))
+                {
+                    var beforeString = beforeValue?.ToString()?.Trim();
+                    var afterString = afterValue?.ToString()?.Trim();
+
+                    if (beforeString != afterString)
+                    {
+                        changeDetails.Add(new FieldChangeDetail
+                        {
+                            FieldName = prop.Name,
+                            BeforeValue = FormatValue(beforeString),
+                            AfterValue = FormatValue(afterString)
+                        });
+                    }
+                }
+                else
+                {
+                    // 其他类型使用默认比较
+                    if (!Equals(beforeValue, afterValue))
+                    {
+                        changeDetails.Add(new FieldChangeDetail
+                        {
+                            FieldName = prop.Name,
+                            BeforeValue = FormatValue(beforeValue),
+                            AfterValue = FormatValue(afterValue)
+                        });
+                    }
+                }
+            }
+
+            return changeDetails;
+        }
+
+        /// <summary>
+        /// 格式化值显示
+        /// </summary>
+        /// <param name="value">原始值</param>
+        /// <returns>格式化后的值</returns>
+        private static string FormatValue(object value)
+        {
+            if (value == null) return "null";
+
+            var strValue = value.ToString();
+
+            // 处理空字符串
+            if (string.IsNullOrEmpty(strValue)) return "空";
+
+            // 处理布尔值
+            if (value is bool boolValue) return boolValue ? "是" : "否";
+
+            // 处理日期时间
+            if (value is DateTime dateTimeValue) return dateTimeValue.ToString("yyyy-MM-dd HH:mm");
+
+            // 处理枚举类型
+            if (value is Enum enumBool) return enumBool.GetDescription();
+
+            return strValue;
+        }
+
+        /// <summary>
+        /// 字段变更详情类
+        /// </summary>
+        private class FieldChangeDetail
+        {
+            public string FieldName { get; set; }
+            public string BeforeValue { get; set; }
+            public string AfterValue { get; set; }
+        }
+
+        /// <summary>
+        /// 获取默认排除的字段列表(包含系统字段和忽略字段)
+        /// </summary>
+        /// <returns>默认排除的字段列表</returns>
+        private static List<string> GetDefaultExcludedFields()
+        {
+            var defaultExcludedFields = new List<string>
+            {
+                nameof(Pm_TaskAllocation.Id),
+                nameof(Pm_TaskAllocation.CreateTime),
+                nameof(Pm_TaskAllocation.CreateUserId),
+                nameof(Pm_TaskAllocation.DeleteTime),
+                nameof(Pm_TaskAllocation.DeleteUserId)
+            };
+
+            return defaultExcludedFields.Distinct().ToList();
+        }
+
+        #endregion
     }
 }