Procházet zdrojové kódy

1、任务分配 新增添加任务操作权限
2、固定任务 新增保存操作权限
3、团组流程 BUG调整、提示节点名称更改为动态实时读取、节点设置实际完成时间逻辑上加上 当前节点未完成更改为已完成。

Lyyyi před 2 dny
rodič
revize
9269183468

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

@@ -1678,6 +1678,24 @@ namespace OASystem.API.Controllers
             }
             }
             #endregion
             #endregion
 
 
+            #region 验证出访时间是否有变化 有变化则重新生成倒推表
+            if (!startTime.ToString("yyyy-MM-dd").Equals(di.VisitDate.ToString("yyyy-MM-dd")))
+            {
+                var msg = "团组成本模块修改出访时间,删除倒推表重新生成";
+                var softDel = await _sqlSugar.Updateable<Grp_InvertedList>()
+                    .SetColumns(x => x.IsDel == 1)
+                    .SetColumns(x => x.DeleteUserId == 4)
+                    .SetColumns(x => x.DeleteTime == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
+                    .SetColumns(x => x.Remark == msg)
+                    .Where(x => x.DiId == dto.Diid)
+                    .ExecuteCommandAsync();
+
+                //默认创建倒推表
+                await _invertedListRep._Create(4, dto.Diid, msg);
+            }
+
+            #endregion
+
             di.VisitDate = startTime;
             di.VisitDate = startTime;
             di.VisitPNumber = dto.VisitPNumber;
             di.VisitPNumber = dto.VisitPNumber;
             di.VisitDays = dto.VisitDays;
             di.VisitDays = dto.VisitDays;
@@ -1735,6 +1753,27 @@ namespace OASystem.API.Controllers
                 {
                 {
                     ffrPrice = groupInfo.PaymentMoney;
                     ffrPrice = groupInfo.PaymentMoney;
                     visitDt = groupInfo.VisitDate.AddDays(-groupInfo.PayDay);
                     visitDt = groupInfo.VisitDate.AddDays(-groupInfo.PayDay);
+
+                    #region 验证出访时间是否有变化 有变化则重新生成倒推表
+
+                    if (DateTime.TryParse(dto.VisitDate, out DateTime startTime))
+                    {
+                        if (!startTime.ToString("yyyy-MM-dd").Equals(groupInfo.VisitDate.ToString("yyyy-MM-dd")))
+                        {
+                            var msg = "团组信息模块修改出访时间,删除倒推表重新生成";
+                            var softDel = await _sqlSugar.Updateable<Grp_InvertedList>()
+                                .SetColumns(x => x.IsDel == 1)
+                                .SetColumns(x => x.DeleteUserId == 4)
+                                .SetColumns(x => x.DeleteTime == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
+                                .SetColumns(x => x.Remark == msg)
+                                .Where(x => x.DiId == dto.Id)
+                                .ExecuteCommandAsync();
+
+                            //默认创建倒推表
+                            await _invertedListRep._Create(dto.UserId, dto.Id, msg);
+                        }
+                    }
+                    #endregion
                 }
                 }
             }
             }
 
 
@@ -17398,7 +17437,6 @@ FROM
             return Ok(JsonView(false));
             return Ok(JsonView(false));
         }
         }
 
 
-
         #region 城市区间交通费
         #region 城市区间交通费
         /// <summary>
         /// <summary>
         /// 团组模块 - 出入境费用 - 草稿 - 移动端 - 基础数据源(境外用车)
         /// 团组模块 - 出入境费用 - 草稿 - 移动端 - 基础数据源(境外用车)

+ 66 - 134
OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs

@@ -1,5 +1,7 @@
 using Aspose.Cells;
 using Aspose.Cells;
+using Dm.util;
 using FluentValidation;
 using FluentValidation;
+using k8s.KubeConfigModels;
 using Markdig;
 using Markdig;
 using Microsoft.AspNetCore.SignalR;
 using Microsoft.AspNetCore.SignalR;
 using OASystem.API.OAMethodLib;
 using OASystem.API.OAMethodLib;
@@ -1049,141 +1051,69 @@ namespace OASystem.API.Controllers
                 groupArr = groupNames.Split(',').Select(part => part.Trim()).ToArray();
                 groupArr = groupNames.Split(',').Select(part => part.Trim()).ToArray();
             }
             }
 
 
-            string whereSql = "", currUserName = "";
-            #region 分页参数处理
-
-            //类型处理
-            if (dto.Type == 0) whereSql = "";
-            else if (dto.Type == 1) //1 由我指派
-            {
-                //whereSql = string.Format(@" And ta.CreateUserId = {0} Or (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
-            }
-            else if (dto.Type == 2)// 2 指派给我
-            {
-                //whereSql = string.Format(@" And (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
-            }
-            //状态 -1 全部 0 未开始 1 进行中 2 待审核 3 未完成 4 已完成
-            if (dto.Status == -1) //全部
-            {
-                whereSql += "";
-            }
-            else
-            {
-                whereSql += string.Format(@" And ta.Status = {0} ", dto.Status);
-            }
-
-            //任务类型
-            if (dto.TaskType == -1) //全部
-            {
-                whereSql += "";
-            }
-            else
-            {
-                whereSql += string.Format(@" And ta.TaskType = {0} ", dto.TaskType);
-            }
-
-            //任务名称
-            if (!string.IsNullOrEmpty(dto.TaskName))
-            {
-                whereSql += string.Format(@" And ta.TaskName Like '%{0}%' ", dto.TaskName);
-            }
-
-            //人员名称
-            string taskUserWhereSql = string.Empty;
-            if (dto.TaskUserId > 0)
-            {
-                var taskUserInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.TaskUserId);
-                if (taskUserInfo != null)
+            //任务人员限定 发布者可看范围内的人员,接受者只能看自己的任务
+            var taskPublisher = await _taskAllocationRep.ValidateTaskPublisher(dto.UserId);
+            var taskUserIds = new List<int>();
+            if (taskPublisher.isTaskPublisher) {
+                taskUserIds = taskPublisher.userIds;
+                //查询指定人员
+                if (dto.TaskUserId > -1)
                 {
                 {
-                    taskUserWhereSql = $" AND [Participant] like '%{taskUserInfo.CnName}%'";
+                    taskUserIds = taskPublisher.userIds.Where(x => x == dto.TaskUserId).ToList();
                 }
                 }
             }
             }
-
-            #endregion
-
-            var currUserInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.Id == dto.UserId);
-            if (currUserInfo != null) currUserName = currUserInfo.CnName;
-
-            string pageSql = string.Format(@"Select
- ROW_NUMBER() OVER(
-        ORDER BY
-          CreateTime Desc
-      ) AS RowNumber,
-  *
-From
-(
-    Select
-      ta.Id,
-      ta.TaskName,
-      ta.TaskContent,
-      s.Name as 'TaskTypeName',
-      ta.TaskPriority,
-      d.DepName,
-      di.TeamName,
-      ta.Status,
-      ta.PredictBeginTime,
-      ta.PredictEndTime,
-      ta.CreateUserId,
-      u.CnName As CreateUserName,
-      ta.CreateTime,
-      ta.Remark,
-      ta.OverTime,
-      (
-        SELECT
-          STUFF(
-            (
-              Select
-                ',' + u.CnName
-              From
-                Pm_TaskRelevanceUser tra
-                Left Join Sys_Users u On tra.UserId = u.Id
-              Where
-                tra.Isdel = 0
-                And tra.TAId = ta.Id FOR XML PATH('')
-            ),
-            1,
-            1,
-            ''
-          )
-      ) As Participant
-      --,(
-      --  SELECT
-      --    STUFF(
-      --      (
-      --        Select
-      --          ',' + u.CnName
-      --        From
-      --          Pm_TaskRelevanceUser tra
-      --          Left Join Sys_Users u On tra.UserId = u.Id
-      --        Where
-      --          tra.Isdel = 0
-      --          And tra.TAId = ta.Id
-      --          And tra.TaskStatus = 4 FOR XML PATH('')
-      --      ),
-      --      1,
-      --      1,
-      --      ''
-      --    )
-      --) As Consummator
-    From
-      Pm_TaskAllocation ta
-      Left Join Sys_Department d On ta.DepId = d.Id
-      Left Join Grp_DelegationInfo di On ta.DiId = di.Id
-      Left Join Sys_Users u On ta.CreateUserId = u.Id
-      left join Sys_SetData s on ta.TaskType = s.Id 
-    Where
-      ta.IsDel = 0 {0}
-  ) As temp
-WHERE
-  [CreateUserName] like '%{1}%' {2}", whereSql, currUserName, taskUserWhereSql);
+            else taskUserIds.Add(dto.UserId);
 
 
             RefAsync<int> total = 0;
             RefAsync<int> total = 0;
-            var _view = await _sqlSugar.SqlQueryable<TaskListView>(pageSql)
-                .WhereIF(groupArr.Any(), x => groupArr.Contains(x.TeamName))
-                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
+            var view = await _sqlSugar.Queryable< Pm_TaskAllocation >()
+                .LeftJoin< Sys_Department >((ta,d) => ta.DepId == d.Id)
+                .LeftJoin< Grp_DelegationInfo >((ta, d,di) => ta.DiId == di.Id)
+                .LeftJoin<Sys_Users>((ta, d, di,u) => ta.CreateUserId == u.Id)
+                .LeftJoin<Sys_SetData>((ta, d, di, u,sd) => ta.TaskType == sd.Id)
+                .Where((ta, d, di, u, sd) => ta.IsDel == 0)
+                //任务发布者和任务接受者
+                .Where((ta, d, di, u, sd) => 
+                    SqlFunc.Subqueryable<Pm_TaskRelevanceUser>()
+                    .Where(tr => tr.TAId == ta.Id && taskUserIds.Contains(tr.UserId))
+                    .Any())
+                //状态 
+                .WhereIF(dto.Status > -1 , (ta, d, di, u, sd) => (int)ta.Status == dto.Status)
+                //任务类型
+                .WhereIF(dto.TaskType > -1, (ta, d, di, u, sd) => ta.TaskType == dto.TaskType)
+                //团组
+                .WhereIF(groupArr.Any(), (ta, d, di, u, sd) => groupArr.Contains(di.TeamName))
+                .OrderByDescending((ta, d, di, u, sd) => ta.CreateTime)
+                .Select((ta, d, di, u, sd) => new TaskListView() {
+                    Id = ta.Id,
+                    TaskName = ta.TaskName,
+                    TaskContent = ta.TaskContent,
+                    TaskTypeName = sd.Name,
+                    TaskPriority = ta.TaskPriority,
+                    DepName = d.DepName,
+                    TeamName = di.TeamName,
+                    Status = (int)ta.Status,
+                    PredictBeginTime = ta.PredictBeginTime,
+                    PredictEndTime = ta.PredictEndTime,
+                    CreateUserId = ta.CreateUserId,
+                    CreateUserName = u.CnName,
+                    CreateTime = ta.CreateTime,
+                    Remark = ta.Remark,
+                    OverTime = ta.OverTime
+                })
+                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+
+            int index = 1;
+            foreach (var item in view)
+            {
+                item.RowNumber = index;
+                //设置参与人
+                var userNames = await _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
+                    .LeftJoin<Sys_Users>((tru, u) => tru.UserId == u.Id)
+                    .Where((tru, u) => tru.IsDel == 0 && tru.TAId == item.Id)
+                    .Select((tru, u) => u.CnName)
+                    .ToListAsync();
+                item.Participant = string.Join("、", userNames);
 
 
-            foreach (var item in _view)
-            {
                 //设置编辑权限
                 //设置编辑权限
                 (bool editPerm, string msg1) = _taskAllocationRep.EditPerm(item.Id, dto.UserId);
                 (bool editPerm, string msg1) = _taskAllocationRep.EditPerm(item.Id, dto.UserId);
                 item.EditPerm = editPerm;
                 item.EditPerm = editPerm;
@@ -1196,9 +1126,11 @@ WHERE
                 item.TaskDetailsPerm = _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
                 item.TaskDetailsPerm = _sqlSugar.Queryable<Pm_TaskRelevanceUser>()
                     .Where(it => it.IsDel == 0 && it.TAId == item.Id && (it.UserId == dto.UserId || it.CreateUserId == dto.UserId))
                     .Where(it => it.IsDel == 0 && it.TAId == item.Id && (it.UserId == dto.UserId || it.CreateUserId == dto.UserId))
                     .Any();
                     .Any();
+
+                index++;
             }
             }
 
 
-            return Ok(JsonView(true, "查询成功!", _view, total));
+            return Ok(JsonView(true, "查询成功!", view, total));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -5365,11 +5297,12 @@ ORDER BY MonthNumber, CollectionDays";
         /// <summary>
         /// <summary>
         /// 公司日常绩效 初始化数据
         /// 公司日常绩效 初始化数据
         /// </summary>
         /// </summary>
+        /// <param name="currUserId">当前用户ID</param>
         /// <returns></returns>
         /// <returns></returns>
-        [HttpGet]
-        public async Task<IActionResult> CompanyDailyKpiInit()
+        [HttpGet("{currUserId}")]
+        public async Task<IActionResult> CompanyDailyKpiInit(int currUserId)
         {
         {
-            return Ok(await _companyDailyKyiRep.InitAsync());
+            return Ok(await _companyDailyKyiRep.InitAsync(currUserId));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -5436,6 +5369,5 @@ ORDER BY MonthNumber, CollectionDays";
 
 
         #endregion
         #endregion
 
 
-
     }
     }
 }
 }

+ 0 - 1
OASystem/OASystem.Api/Controllers/SystemController.cs

@@ -4856,7 +4856,6 @@ GROUP BY
 6586,
 6586,
 2613,
 2613,
 2364,
 2364,
-
             };
             };
 
 
             var datas = await _sqlSugar.Queryable<Crm_NewClientData>().Where(x => x.IsDel == 0 && yqyClientIds.Contains(x.Id)).ToListAsync();
             var datas = await _sqlSugar.Queryable<Crm_NewClientData>().Where(x => x.IsDel == 0 && yqyClientIds.Contains(x.Id)).ToListAsync();

+ 1 - 1
OASystem/OASystem.Domain/Entities/Groups/Grp_ProcessOverview.cs

@@ -362,7 +362,7 @@ namespace OASystem.Domain.Entities.Groups
         /// <summary>
         /// <summary>
         /// 操作描述
         /// 操作描述
         /// </summary>
         /// </summary>
-        [SugarColumn(ColumnName = "OpDesc", ColumnDescription = "操作描述", ColumnDataType = "varchar(500)")]
+        [SugarColumn(ColumnName = "OpDesc", ColumnDescription = "操作描述", ColumnDataType = "varchar(max)")]
         public string OpDesc { get; set; }
         public string OpDesc { get; set; }
 
 
         /// <summary>
         /// <summary>

+ 7 - 12
OASystem/OASystem.Domain/ViewModels/PersonnelModule/TaskAllocationView.cs

@@ -24,7 +24,7 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
         /// <summary>
         /// <summary>
         /// 任务操作权限
         /// 任务操作权限
         /// </summary>
         /// </summary>
-        public TaskOperationAudit TaskOperationAudit { get; set; }
+        public TaskOperationPerm OperationPerm { get; set; }
         /// <summary>
         /// <summary>
         /// 任务名称 Items
         /// 任务名称 Items
         /// </summary>
         /// </summary>
@@ -82,37 +82,32 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
     /// <summary>
     /// <summary>
     /// 任务操作权限
     /// 任务操作权限
     /// </summary>
     /// </summary>
-    public class TaskOperationAudit
+    public class TaskOperationPerm
     {
     {
         /// <summary>
         /// <summary>
         /// 任务添权限
         /// 任务添权限
-        /// 0 否 1 是
         /// </summary>
         /// </summary>
-        public int TaskAddAudit { get; set; } = 0;
+        public bool IsAddPerm { get; set; } = false;
 
 
         /// <summary>
         /// <summary>
         /// 任务删除权限
         /// 任务删除权限
-        /// 0 否 1 是
         /// </summary>
         /// </summary>
-        public int TaskDelAudit { get; set; } = 0;
+        public bool IsDelPerm { get; set; } = false;
 
 
         /// <summary>
         /// <summary>
         /// 任务终止权限
         /// 任务终止权限
-        /// 0 否 1 是
         /// </summary>
         /// </summary>
-        public int TasStopAudit { get; set; } = 0;
+        public bool IsStopPerm { get; set; } = false;
 
 
         /// <summary>
         /// <summary>
         /// 任务确认权限
         /// 任务确认权限
-        /// 0 否 1 是
         /// </summary>
         /// </summary>
-        public int TaskComfirmAudit { get; set; } = 0;
+        public bool IsComfirmPerm { get; set; } = false;
 
 
         /// <summary>
         /// <summary>
         /// 任务评分权限
         /// 任务评分权限
-        /// 0 否 1 是
         /// </summary>
         /// </summary>
-        public int TaskScoreAudit { get; set; } = 0;
+        public bool IsScorePerm { get; set; } = false;
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 3 - 2
OASystem/OASystem.Infrastructure/Repositories/Groups/InvertedListRepository.cs

@@ -167,7 +167,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
         /// </summary>
         /// </summary>
         /// <param name="diId"></param>
         /// <param name="diId"></param>
         /// <returns></returns>
         /// <returns></returns>
-        public async Task<Result> _Create(int userId,int diId)
+        public async Task<Result> _Create(int userId,int diId,string remark = "")
         {
         {
             #region 参数验证
             #region 参数验证
             if (diId < 1)
             if (diId < 1)
@@ -196,7 +196,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 return _result;
                 return _result;
             }
             }
 
 
-            if (string.IsNullOrEmpty( groupInfo.VisitDate.ToString()))
+            if (string.IsNullOrEmpty(groupInfo.VisitDate.ToString()))
             {
             {
                 _result.Msg = @$"团组出访时间未填写,不可创建!";
                 _result.Msg = @$"团组出访时间未填写,不可创建!";
                 return _result;
                 return _result;
@@ -275,6 +275,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 PreTripMeetingDt = visitDt.AddDays(preTripMeeting_advanceDays).ToString("yyyy-MM-dd"),
                 PreTripMeetingDt = visitDt.AddDays(preTripMeeting_advanceDays).ToString("yyyy-MM-dd"),
                 AirportdDropOffDt = visitDt.AddDays(airportdDropOff_advanceDays).ToString("yyyy-MM-dd"),
                 AirportdDropOffDt = visitDt.AddDays(airportdDropOff_advanceDays).ToString("yyyy-MM-dd"),
                 CreateUserId = userId,
                 CreateUserId = userId,
+                Remark = remark
             };
             };
 
 
             if (!string.IsNullOrEmpty(sqqzRemark)) info.SendVisaRemark = sqqzRemark;
             if (!string.IsNullOrEmpty(sqqzRemark)) info.SendVisaRemark = sqqzRemark;

+ 237 - 86
OASystem/OASystem.Infrastructure/Repositories/Groups/ProcessOverviewRepository.cs

@@ -6,6 +6,7 @@ using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.Entities.Resource;
 using OASystem.Domain.Entities.Resource;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Domain.ViewModels.Groups;
 using Org.BouncyCastle.Asn1.X500;
 using Org.BouncyCastle.Asn1.X500;
+using System.Diagnostics;
 using System.Reflection;
 using System.Reflection;
 using System.Runtime.Intrinsics.Arm;
 using System.Runtime.Intrinsics.Arm;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
@@ -37,11 +38,11 @@ namespace OASystem.Infrastructure.Repositories.Groups
         {
         {
             var processs = new List<Grp_ProcessOverview>();
             var processs = new List<Grp_ProcessOverview>();
 
 
-            //团组验证
+            // 团组验证
             var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(g => g.Id == groupId);
             var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(g => g.Id == groupId);
             if (groupInfo == null) return processs;
             if (groupInfo == null) return processs;
 
 
-            // 检查是否已存在流程
+            // 流程验证
             var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>()
             var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>()
                 .Where(p => p.IsDel == 0 && p.GroupId == groupId)
                 .Where(p => p.IsDel == 0 && p.GroupId == groupId)
                 .ToListAsync();
                 .ToListAsync();
@@ -65,18 +66,14 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 .ToListAsync();
                 .ToListAsync();
 
 
             #region 商邀报批流程
             #region 商邀报批流程
-            var custInfo = await _sqlSugar.Queryable<Grp_TourClientList>()
-                .Where(c => c.DiId == groupId && c.IsDel == 0)
-                .OrderByDescending(c => c.CreateTime)
-                .FirstAsync();
-            string oaNode2Tips = "客户提供完整名单后,2周内取得邀请函(翻译件)。";
-            if (custInfo != null)
-            {
-                oaNode2Tips = $"请于{custInfo.CreateTime.AddDays(14):yyyy年MM月dd日}内完成该项工作(客户提供完整名单后,2周内取得邀请函(翻译件))";
-            }
 
 
-            var oaNode4Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(按进度实际公务活动落实情况,出发前5日落实公务)";
-            var oaNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组结束前完成)";
+            string oaNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 1);
+            string oaNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 2);
+            string oaNode3Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 3);
+            string oaNode4Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 4);
+            string oaNode5Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 5);
+            string oaNode6Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 6);
+            string oaNode7Tips = NodeTipsMsg(groupInfo, GroupProcessType.Invitation, 7);
 
 
             //节点可操作用户列表
             //节点可操作用户列表
             var oaNodeOpUsers = users.Where(u =>
             var oaNodeOpUsers = users.Where(u =>
@@ -87,12 +84,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 Grp_ProcessOverview.Create(groupId, 1, GroupProcessType.Invitation, ProcessStatus.InProgress, currUserId,
                 Grp_ProcessOverview.Create(groupId, 1, GroupProcessType.Invitation, ProcessStatus.InProgress, currUserId,
                 new List<Grp_ProcessNode>()
                 new List<Grp_ProcessNode>()
                     {
                     {
-                        Grp_ProcessNode.Create(1, "报批基础资料准备","更新报批行程和请示,提供其他报批所需材料,4个工作日内完成。",ProcessStatus.InProgress, true,false,false,false,currUserId,oaNodeOpUsers),
+                        Grp_ProcessNode.Create(1, "报批基础资料准备",oaNode1Tips,ProcessStatus.InProgress, true,false,false,false,currUserId,oaNodeOpUsers),
                         Grp_ProcessNode.Create(2, "报批邀请函资料准备",oaNode2Tips, ProcessStatus.InProgress, false,false,false,false,currUserId,oaNodeOpUsers),
                         Grp_ProcessNode.Create(2, "报批邀请函资料准备",oaNode2Tips, ProcessStatus.InProgress, false,false,false,false,currUserId,oaNodeOpUsers),
-                        Grp_ProcessNode.Create(3, "获得批件","提供完整的报批全套资源。",ProcessStatus.InProgress, false,false,false,false, currUserId ,oaNodeOpUsers),
+                        Grp_ProcessNode.Create(3, "获得批件",oaNode3Tips,ProcessStatus.InProgress, false,false,false,false, currUserId ,oaNodeOpUsers),
                         Grp_ProcessNode.Create(4, "对接公务",oaNode4Tips,ProcessStatus.InProgress, false,false,false,false, currUserId,oaNodeOpUsers),
                         Grp_ProcessNode.Create(4, "对接公务",oaNode4Tips,ProcessStatus.InProgress, false,false,false,false, currUserId,oaNodeOpUsers),
-                        Grp_ProcessNode.Create(5, "参与翻译对接","",ProcessStatus.InProgress, false,false,false,true, currUserId,oaNodeOpUsers),
-                        Grp_ProcessNode.Create(6, "商邀文案配合","",ProcessStatus.InProgress, false,false,false,false, currUserId,oaNodeOpUsers),
+                        Grp_ProcessNode.Create(5, "参与翻译对接",oaNode5Tips,ProcessStatus.InProgress, false,false,false,true, currUserId,oaNodeOpUsers),
+                        Grp_ProcessNode.Create(6, "商邀文案配合",oaNode6Tips,ProcessStatus.InProgress, false,false,false,false, currUserId,oaNodeOpUsers),
                         Grp_ProcessNode.Create(7, "票据上传(相关票据)",oaNode7Tips,ProcessStatus.InProgress, false,false,true,false, currUserId,oaNodeOpUsers),
                         Grp_ProcessNode.Create(7, "票据上传(相关票据)",oaNode7Tips,ProcessStatus.InProgress, false,false,true,false, currUserId,oaNodeOpUsers),
                     }));
                     }));
             #endregion
             #endregion
@@ -115,8 +112,9 @@ namespace OASystem.Infrastructure.Repositories.Groups
                     visaDefualtNodes.Add(VisaProcessNode.Info(i, visaCountries[i - 1].ToString()));
                     visaDefualtNodes.Add(VisaProcessNode.Info(i, visaCountries[i - 1].ToString()));
                 }
                 }
 
 
-                var visaNode2Tips = $"请于{groupInfo.VisitDate:yyyy年MM月dd日}内完成该项工作(按进度实际签证办理落实情况,团组出发前上传票据。)";
-                visaNodes.Add(Grp_ProcessNode.Create(1, "签证信息", "", ProcessStatus.InProgress, true, false, false, false, currUserId, visaNodeOpUsers, JsonConvert.SerializeObject(visaDefualtNodes)));
+                string visaNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.Visa, 1);
+                string visaNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.Visa, 2);
+                visaNodes.Add(Grp_ProcessNode.Create(1, "签证信息", visaNode1Tips, ProcessStatus.InProgress, true, false, false, false, currUserId, visaNodeOpUsers, JsonConvert.SerializeObject(visaDefualtNodes)));
                 visaNodes.Add(Grp_ProcessNode.Create(2, "票据上传(明细表、费用票据、保单及超支费用账单)", visaNode2Tips, ProcessStatus.InProgress, false, false, true, false, currUserId, oaNodeOpUsers));
                 visaNodes.Add(Grp_ProcessNode.Create(2, "票据上传(明细表、费用票据、保单及超支费用账单)", visaNode2Tips, ProcessStatus.InProgress, false, false, true, false, currUserId, oaNodeOpUsers));
             }
             }
 
 
@@ -124,19 +122,14 @@ namespace OASystem.Infrastructure.Repositories.Groups
             #endregion
             #endregion
 
 
             #region 机票流程
             #region 机票流程
-            string airNode1Tips = "建团后打勾确认出团的时候开始24小时内。";
-            if (groupInfo.Step == 1 || groupInfo.Step == 2)
-            {
-                if (groupInfo.StepOperationTime.HasValue)
-                {
-                    airNode1Tips = $"请于{groupInfo.StepOperationTime.Value.AddDays(1):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始24小时内)";
-                }
-            }
-
-            var airNode3Tips = $"完成机票采购确认(含预算核对、出票确认等)";
-            var airNode5Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5日)";
-            var airNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组归国后5个工作日内)";
-            var airNode8Tips = $"1. 票据上传(机票报销蓝联、行程单及机票说明) \r\n 2. 请于{groupInfo.VisitEndDate.AddDays(10):yyyy年MM月dd日}内完成该项工作(团组归国后10个工作日内) *按机票报价*0.999折扣出具机票报销蓝联、行程单及机票说明";
+            string airNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 1);
+            string airNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 2);
+            string airNode3Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 3);
+            string airNode4Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 4);
+            string airNode5Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 5);
+            string airNode6Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 6);
+            string airNode7Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 7);
+            string airNode8Tips = NodeTipsMsg(groupInfo, GroupProcessType.AirTicket, 8);
 
 
             //节点可操作用户列表
             //节点可操作用户列表
             var airNodeOpUsers = users.Where(u =>
             var airNodeOpUsers = users.Where(u =>
@@ -147,12 +140,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 Grp_ProcessOverview.Create(groupId, 3, GroupProcessType.AirTicket, ProcessStatus.InProgress, currUserId,
                 Grp_ProcessOverview.Create(groupId, 3, GroupProcessType.AirTicket, ProcessStatus.InProgress, currUserId,
                 new List<Grp_ProcessNode>()
                 new List<Grp_ProcessNode>()
                     {
                     {
-                        Grp_ProcessNode.Create(1, "初步拟定航程方案及价格",   airNode1Tips, ProcessStatus.InProgress, true,false,false,false, currUserId ,airNodeOpUsers),
-                        Grp_ProcessNode.Create(2, "机票占位、续位",   "", ProcessStatus.UnStarted, false,false,false,false,currUserId,airNodeOpUsers ),
-                        Grp_ProcessNode.Create(3, "完成机票采购确认",  airNode3Tips, ProcessStatus.UnStarted,false,false,false,false, currUserId, airNodeOpUsers),
-                        Grp_ProcessNode.Create(4, "进行出票操作并核查信息", "", ProcessStatus.UnStarted, false,false,false,false, currUserId, airNodeOpUsers),
-                        Grp_ProcessNode.Create(5, "机票已出",  airNode5Tips, ProcessStatus.UnStarted, false,false,false,false, currUserId, airNodeOpUsers),
-                        Grp_ProcessNode.Create(6, "完成机票选座", "", ProcessStatus.UnStarted, false,false,false,false,currUserId, airNodeOpUsers),
+                        Grp_ProcessNode.Create(1, "初步拟定航程方案及价格", airNode1Tips, ProcessStatus.InProgress, true,false,false,false, currUserId ,airNodeOpUsers),
+                        Grp_ProcessNode.Create(2, "机票占位、续位", airNode2Tips, ProcessStatus.UnStarted, false,false,false,false,currUserId,airNodeOpUsers ),
+                        Grp_ProcessNode.Create(3, "完成机票采购确认", airNode3Tips, ProcessStatus.UnStarted,false,false,false,false, currUserId, airNodeOpUsers),
+                        Grp_ProcessNode.Create(4, "进行出票操作并核查信息", airNode4Tips, ProcessStatus.UnStarted, false,false,false,false, currUserId, airNodeOpUsers),
+                        Grp_ProcessNode.Create(5, "机票已出", airNode5Tips, ProcessStatus.UnStarted, false,false,false,false, currUserId, airNodeOpUsers),
+                        Grp_ProcessNode.Create(6, "完成机票选座", airNode6Tips, ProcessStatus.UnStarted, false,false,false,false,currUserId, airNodeOpUsers),
                         Grp_ProcessNode.Create(7, "票据上传(机票超支费用账单)", airNode7Tips, ProcessStatus.UnStarted, false,false,true,false, currUserId,airNodeOpUsers),
                         Grp_ProcessNode.Create(7, "票据上传(机票超支费用账单)", airNode7Tips, ProcessStatus.UnStarted, false,false,true,false, currUserId,airNodeOpUsers),
                         Grp_ProcessNode.Create(8, "票据上传", airNode8Tips, ProcessStatus.UnStarted, false,false,true,false, currUserId, airNodeOpUsers)
                         Grp_ProcessNode.Create(8, "票据上传", airNode8Tips, ProcessStatus.UnStarted, false,false,true,false, currUserId, airNodeOpUsers)
                     }
                     }
@@ -162,17 +155,11 @@ namespace OASystem.Infrastructure.Repositories.Groups
 
 
             #region 酒店流程
             #region 酒店流程
 
 
-            string hotelNode1Tips = "1. 筛选并按照预算标准,对目标酒店进行询价、比价、谈价 \r\n2. 建团后打勾确认出团的时候开始2个工作日。";
-            if (groupInfo.Step == 1 || groupInfo.Step == 2)
-            {
-                if (groupInfo.StepOperationTime.HasValue)
-                {
-                    hotelNode1Tips = $"请于{groupInfo.StepOperationTime.Value.AddDays(2):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始2个工作日)";
-                }
-            }
-
-            var hotelNode4Tips = $"1.行前再次确认酒店订单、付款状态及入住安排 \r\n 2.请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5天)";
-            var hotelNode5Tips = $"1.行程结束后整理酒店发票(含超支费用发票)与结算 \r\n 2.请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组结束后5天内)";
+            string hotelNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.Hotel, 1);
+            string hotelNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.Hotel, 2);
+            string hotelNode3Tips = NodeTipsMsg(groupInfo, GroupProcessType.Hotel, 3);
+            string hotelNode4Tips = NodeTipsMsg(groupInfo, GroupProcessType.Hotel, 4);
+            string hotelNode5Tips = NodeTipsMsg(groupInfo, GroupProcessType.Hotel, 5);
 
 
             //节点可操作用户列表
             //节点可操作用户列表
             var hotelNodeOpUsers = users.Where(u =>
             var hotelNodeOpUsers = users.Where(u =>
@@ -184,8 +171,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
                      new List<Grp_ProcessNode>()
                      new List<Grp_ProcessNode>()
                     {
                     {
                         Grp_ProcessNode.Create(1, "按照预算,询价、比价、谈价", hotelNode1Tips, ProcessStatus.InProgress, true, false, false, false, currUserId, hotelNodeOpUsers),
                         Grp_ProcessNode.Create(1, "按照预算,询价、比价、谈价", hotelNode1Tips, ProcessStatus.InProgress, true, false, false, false, currUserId, hotelNodeOpUsers),
-                        Grp_ProcessNode.Create(2, "获取酒店确认函与入住名单核对", "", ProcessStatus.UnStarted, false, false, false,false, currUserId , hotelNodeOpUsers),
-                        Grp_ProcessNode.Create(3, "预订酒店并录入OA",  "", ProcessStatus.UnStarted,false, false, false,false,currUserId , hotelNodeOpUsers),
+                        Grp_ProcessNode.Create(2, "获取酒店确认函与入住名单核对", hotelNode2Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId , hotelNodeOpUsers),
+                        Grp_ProcessNode.Create(3, "预订酒店并录入OA", hotelNode3Tips, ProcessStatus.UnStarted,false, false, false,false,currUserId , hotelNodeOpUsers),
                         Grp_ProcessNode.Create(4, "行前再次确认酒店相关情况",  hotelNode4Tips,ProcessStatus.UnStarted, false, false, false,false,currUserId , hotelNodeOpUsers),
                         Grp_ProcessNode.Create(4, "行前再次确认酒店相关情况",  hotelNode4Tips,ProcessStatus.UnStarted, false, false, false,false,currUserId , hotelNodeOpUsers),
                         Grp_ProcessNode.Create(5, "行程结束后整理酒店发票与结算",  hotelNode5Tips, ProcessStatus.UnStarted, false, false, true,false, currUserId ,hotelNodeOpUsers),
                         Grp_ProcessNode.Create(5, "行程结束后整理酒店发票与结算",  hotelNode5Tips, ProcessStatus.UnStarted, false, false, true,false, currUserId ,hotelNodeOpUsers),
                     }
                     }
@@ -194,32 +181,13 @@ namespace OASystem.Infrastructure.Repositories.Groups
             #endregion
             #endregion
 
 
             #region 地接流程
             #region 地接流程
-            var airTripCodeInfo = await _sqlSugar.Queryable<Air_TicketBlackCode>()
-                .Where(x => x.IsDel == 0 && x.DiId == groupId)
-                .OrderByDescending(x => x.CreateTime)
-                .FirstAsync();
-            string opNode1Tips = $"机票行程代码最后一段录入后1个工作日内。";
-            if (airTripCodeInfo != null)
-            {
-                opNode1Tips = $"请于{airTripCodeInfo.CreateTime.AddDays(1):yyyy年MM月dd日}内完成该项工作(机票行程代码最后一段录入后1个工作日内)";
-            }
-
-            string opNode2Tips = $"1.联系并询价地接、餐厅、用车、景点等供应商 \r\n 2. 请于{groupInfo.CreateTime.AddDays(7):yyyy年MM月dd日}内完成该项工作(建团完成后7个工作日内)";
-            string opNode3Tips = $"请于{groupInfo.CreateTime.AddDays(10):yyyy年MM月dd日}内完成该项工作(上一步往后3个工作日内)";
-            string opNode4Tips = $"请于{groupInfo.CreateTime.AddDays(12):yyyy年MM月dd日}内完成该项工作(上一步往后2个工作日内)";
-
-            var backListInfo = await _sqlSugar.Queryable<Grp_InvertedList>().Where(x => x.DiId == groupId && x.IsDel == 0).FirstAsync();
-            string opNode5Tips = $"1.制定最终《行程单》及《出行手册》 \r\n2. 倒推表里开行前会 -3天。";
-            if (backListInfo != null)
-            {
-
-                if (DateTime.TryParse(backListInfo.PreTripMeetingDt, out DateTime dateTime))
-                {
-                    opNode5Tips = $"请于{dateTime.AddDays(-3):yyyy年MM月dd日}内完成该项工作(倒推表里开行前会 -3天)";
-                }
-            }
-
-            string opNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组归国后5个工作日内) *上传最终报批行程,确定城市间交通最终版报价分配;地接账单(清楚标注超时及其他项超支费用)、地接交通费用原始票据、城市间交通明细表;";
+            string opNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 1);
+            string opNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 2);
+            string opNode3Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 3);
+            string opNode4Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 4);
+            string opNode5Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 5);
+            string opNode6Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 6);
+            string opNode7Tips = NodeTipsMsg(groupInfo, GroupProcessType.LocalGuide, 7);
 
 
             //节点可操作用户列表
             //节点可操作用户列表
             var opNodeOpUsers = users.Where(u =>
             var opNodeOpUsers = users.Where(u =>
@@ -235,7 +203,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                         Grp_ProcessNode.Create(3,"提交供应商报价及比价表", opNode3Tips, ProcessStatus.UnStarted, false, false, false, false,currUserId,opNodeOpUsers),
                         Grp_ProcessNode.Create(3,"提交供应商报价及比价表", opNode3Tips, ProcessStatus.UnStarted, false, false, false, false,currUserId,opNodeOpUsers),
                         Grp_ProcessNode.Create(4,"执行采购流程", opNode4Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId,opNodeOpUsers),
                         Grp_ProcessNode.Create(4,"执行采购流程", opNode4Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId,opNodeOpUsers),
                         Grp_ProcessNode.Create(5,"制定最终行程单及出行手册", opNode5Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId ,opNodeOpUsers),
                         Grp_ProcessNode.Create(5,"制定最终行程单及出行手册", opNode5Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId ,opNodeOpUsers),
-                        Grp_ProcessNode.Create(6,"送机", "", ProcessStatus.UnStarted, false, false, false,false, currUserId,opNodeOpUsers ),
+                        Grp_ProcessNode.Create(6,"送机", opNode6Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId,opNodeOpUsers ),
                         Grp_ProcessNode.Create(7,"最终版报批行程、票据上传", opNode7Tips, ProcessStatus.UnStarted, false, false, true, false,currUserId,opNodeOpUsers )
                         Grp_ProcessNode.Create(7,"最终版报批行程、票据上传", opNode7Tips, ProcessStatus.UnStarted, false, false, true, false,currUserId,opNodeOpUsers )
                     }
                     }
                 )
                 )
@@ -244,8 +212,10 @@ namespace OASystem.Infrastructure.Repositories.Groups
             #endregion
             #endregion
 
 
             #region 费用结算流程
             #region 费用结算流程
-            var feeNode3Tips = $"1.整理统计团组超支费用、三公报销资料给到各单位 \r\n 2. 请于{groupInfo.VisitEndDate.AddDays(12):yyyy年MM月dd日}内完成该项工作(团组归国后12个工作日内)";
-
+            var feeNode1Tips = NodeTipsMsg(groupInfo, GroupProcessType.FeeSettle, 1);
+            var feeNode2Tips = NodeTipsMsg(groupInfo, GroupProcessType.FeeSettle, 2);
+            var feeNode3Tips = NodeTipsMsg(groupInfo, GroupProcessType.FeeSettle, 3);
+            var feeNode4Tips = NodeTipsMsg(groupInfo, GroupProcessType.FeeSettle, 4);
             //节点可操作用户列表
             //节点可操作用户列表
             var feeNodeOpUsers = users.Where(u =>
             var feeNodeOpUsers = users.Where(u =>
                 u.JobName != null && u.JobName.Contains("会计") && u.CnName.Equals("曾艳")
                 u.JobName != null && u.JobName.Contains("会计") && u.CnName.Equals("曾艳")
@@ -255,10 +225,10 @@ namespace OASystem.Infrastructure.Repositories.Groups
                 Grp_ProcessOverview.Create(groupId, 6, GroupProcessType.FeeSettle, ProcessStatus.InProgress, currUserId,
                 Grp_ProcessOverview.Create(groupId, 6, GroupProcessType.FeeSettle, ProcessStatus.InProgress, currUserId,
                     new List<Grp_ProcessNode>()
                     new List<Grp_ProcessNode>()
                     {
                     {
-                        Grp_ProcessNode.Create(1, "城市间交通报批金额核定", "团组报批前", ProcessStatus.InProgress, true, true, false,false,currUserId,feeNodeOpUsers),
-                        Grp_ProcessNode.Create(2, "团组全程各段机票打票金额的核定", "团组报批后、订票前", ProcessStatus.UnStarted, false, false, false,false,currUserId,feeNodeOpUsers),
+                        Grp_ProcessNode.Create(1, "城市间交通报批金额核定", feeNode1Tips, ProcessStatus.InProgress, true, true, false,false,currUserId,feeNodeOpUsers),
+                        Grp_ProcessNode.Create(2, "团组城市间交通及国际机票数据分配的合理性核对", feeNode2Tips, ProcessStatus.UnStarted, false, false, false,false,currUserId,feeNodeOpUsers),
                         Grp_ProcessNode.Create(3, "整理统计相关财务资料给到各单位", feeNode3Tips, ProcessStatus.UnStarted, false, false, false,false,currUserId,feeNodeOpUsers),
                         Grp_ProcessNode.Create(3, "整理统计相关财务资料给到各单位", feeNode3Tips, ProcessStatus.UnStarted, false, false, false,false,currUserId,feeNodeOpUsers),
-                        Grp_ProcessNode.Create(4, "费用结算完毕", "", ProcessStatus.UnStarted, false, false, false,false, currUserId , feeNodeOpUsers),
+                        Grp_ProcessNode.Create(4, "费用结算完毕", feeNode4Tips, ProcessStatus.UnStarted, false, false, false,false, currUserId , feeNodeOpUsers),
                     }
                     }
                 )
                 )
             );
             );
@@ -440,6 +410,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
                             operatorName = name;
                             operatorName = name;
                         }
                         }
 
 
+                        string nodeTipsMsg = NodeTipsMsg(groupInfo, p.ProcessType, n.NodeOrder);
+
                         return new
                         return new
                         {
                         {
                             n.Id,
                             n.Id,
@@ -452,7 +424,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
                             OpeateTime = n.OperationTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-",
                             OpeateTime = n.OperationTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-",
                             ActualDone = n.ActualDone?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
                             ActualDone = n.ActualDone?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
                             n.OpUserList,    //可操作用户列表
                             n.OpUserList,    //可操作用户列表
-                            n.NodeDescTips,
+                            NodeDescTips = nodeTipsMsg,
                             isEnaAssistBtn,  // 是否启用财务流程首节点协助按钮
                             isEnaAssistBtn,  // 是否启用财务流程首节点协助按钮
                             n.IsAssist,      // 财务流程首节点 存储值
                             n.IsAssist,      // 财务流程首节点 存储值
                             isEnaFileUpBtn,  // 是否启用上传文件按钮
                             isEnaFileUpBtn,  // 是否启用上传文件按钮
@@ -468,6 +440,180 @@ namespace OASystem.Infrastructure.Repositories.Groups
             return new Result { Code = 200, Data = processes, Msg = "查询成功!" };
             return new Result { Code = 200, Data = processes, Msg = "查询成功!" };
         }
         }
 
 
+        /// <summary>
+        /// 节点提示消息
+        /// </summary>
+        /// <param name="groupInfo"></param>
+        /// <param name="procType"></param>
+        /// <param name="nodeOrder"></param>
+        /// <returns></returns>
+        public string NodeTipsMsg(Grp_DelegationInfo groupInfo, GroupProcessType procType, int nodeOrder)
+        {
+            string msg = string.Empty;
+            int groupId = groupInfo.Id;
+            switch (procType)
+            {
+                case GroupProcessType.Invitation:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            msg = "更新报批行程和请示,提供其他报批所需材料,4个工作日内完成。";
+                            break;
+                        case 2:
+                            var custInfo = _sqlSugar.Queryable<Grp_TourClientList>()
+                                .Where(c => c.DiId == groupId && c.IsDel == 0)
+                                .OrderByDescending(c => c.CreateTime)
+                                .First();
+                            msg = "客户提供完整名单后,2周内取得邀请函(翻译件)。";
+                            if (custInfo != null)
+                            {
+                                msg = $"请于{custInfo.CreateTime.AddDays(14):yyyy年MM月dd日}内完成该项工作(客户提供完整名单后,2周内取得邀请函(翻译件))";
+                            }
+                            break;
+                        case 3:
+                            msg = "提供完整的报批全套资源。";
+                            break;
+                        case 4:
+                            msg = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(按进度实际公务活动落实情况,出发前5日落实公务)";
+                            break;
+                        case 5:
+                            break;
+                        case 6:
+                            break;
+                        case 7:
+                            msg = $"请于{groupInfo.VisitEndDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组结束前完成)";
+                            break;
+                    }
+                    break;
+                case GroupProcessType.Visa:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            break;
+                        case 2:
+                            msg = $"请于{groupInfo.VisitDate:yyyy年MM月dd日}内完成该项工作(按进度实际签证办理落实情况,团组出发前上传票据。)";
+                            break;
+                    }
+                    break;
+                case GroupProcessType.AirTicket:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            msg = "建团后打勾确认出团的时候开始24小时内。";
+                            if (groupInfo.Step == 1 || groupInfo.Step == 2)
+                            {
+                                if (groupInfo.StepOperationTime.HasValue)
+                                {
+                                    msg = $"请于{groupInfo.StepOperationTime.Value.AddDays(1):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始24小时内)";
+                                }
+                            }
+                            break;
+                        case 2:
+                            break;
+                        case 3:
+                            msg = $"完成机票采购确认(含预算核对、出票确认等)";
+                            break;
+                        case 4:
+                            break;
+                        case 5:
+                            msg = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5日)";
+                            break;
+                        case 6:
+                            break;
+                        case 7:
+                            msg = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(机票蓝联打票及上传机票超支费用账单,团组归国后5个工作日内)";
+                            break;
+                        case 8:
+                            msg = $"1. 票据上传(机票报销蓝联、行程单及机票说明) \r\n 2. 请于{groupInfo.VisitEndDate.AddDays(10):yyyy年MM月dd日}内完成该项工作(团组归国后10个工作日内) *按机票报价*0.999折扣出具机票报销蓝联、行程单及机票说明";
+                            break;
+                    }
+                    break;
+                case GroupProcessType.Hotel:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            msg = "1. 筛选并按照预算标准,对目标酒店进行询价、比价、谈价 \r\n2. 建团后打勾确认出团的时候开始2个工作日。";
+                            if (groupInfo.Step == 1 || groupInfo.Step == 2)
+                            {
+                                if (groupInfo.StepOperationTime.HasValue)
+                                {
+                                    msg = $"请于{groupInfo.StepOperationTime.Value.AddDays(2):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始2个工作日)";
+                                }
+                            }
+                            break;
+                        case 2:
+                            break;
+                        case 3:
+                            break;
+                        case 4:
+                            msg = $"1.行前再次确认酒店订单、付款状态及入住安排 \r\n 2.请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5天)";
+                            break;
+                        case 5:
+                            msg = $"1.行程结束后整理酒店发票(含超支费用发票)与结算 \r\n 2.请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组结束后5天内)";
+                            break;
+                    }
+                    break;
+                case GroupProcessType.LocalGuide:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            var airTripCodeInfo = _sqlSugar.Queryable<Air_TicketBlackCode>()
+                                .Where(x => x.IsDel == 0 && x.DiId == groupId)
+                                .OrderByDescending(x => x.CreateTime)
+                                .First();
+                            msg = $"机票行程代码最后一段录入后1个工作日内。";
+                            if (airTripCodeInfo != null)
+                            {
+                                msg = $"请于{airTripCodeInfo.CreateTime.AddDays(1):yyyy年MM月dd日}内完成该项工作(机票行程代码最后一段录入后1个工作日内)";
+                            }
+                            break;
+                        case 2:
+                            msg = $"1.联系并询价地接、餐厅、用车、景点等供应商 \r\n 2. 请于{groupInfo.CreateTime.AddDays(7):yyyy年MM月dd日}内完成该项工作(建团完成后7个工作日内)";
+                            break;
+                        case 3:
+                            msg = $"请于{groupInfo.CreateTime.AddDays(10):yyyy年MM月dd日}内完成该项工作(上一步往后3个工作日内)";
+                            break;
+                        case 4:
+                            msg = $"请于{groupInfo.CreateTime.AddDays(12):yyyy年MM月dd日}内完成该项工作(上一步往后2个工作日内)";
+                            break;
+                        case 5:
+                            var backListInfo = _sqlSugar.Queryable<Grp_InvertedList>().Where(x => x.DiId == groupId && x.IsDel == 0).First();
+                            msg = $"1.制定最终《行程单》及《出行手册》 \r\n2. 倒推表里开行前会 -3天。";
+                            if (backListInfo != null)
+                            {
+                                if (DateTime.TryParse(backListInfo.PreTripMeetingDt, out DateTime dateTime))
+                                {
+                                    msg = $"请于{dateTime.AddDays(-3):yyyy年MM月dd日}内完成该项工作(倒推表里开行前会 -3天)";
+                                }
+                            }
+                            break;
+                        case 6:
+                            break;
+                        case 7:
+                            msg = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组归国后5个工作日内) *上传最终报批行程,确定城市间交通最终版报价分配;地接账单(清楚标注超时及其他项超支费用)、地接交通费用原始票据、城市间交通明细表;";
+                            break;
+                    }
+                    break;
+                case GroupProcessType.FeeSettle:
+                    switch (nodeOrder)
+                    {
+                        case 1:
+                            msg = "团组报批前";
+                            break;
+                        case 2:
+                            msg = "团组报批前三公费用表";
+                            break;
+                        case 3:
+                            msg = $"1.整理统计团组超支费用、三公报销资料给到各单位 \r\n 2. 请于{groupInfo.VisitEndDate.AddDays(12):yyyy年MM月dd日}内完成该项工作(团组归国后12个工作日内)";
+                            break;
+                        case 4:
+                            break;
+                    }
+                    break;
+            }
+            return msg;
+        }
+
         /// <summary>
         /// <summary>
         /// 更新节点状态
         /// 更新节点状态
         /// </summary>
         /// </summary>
@@ -781,7 +927,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
             if (allSubNodesCompleted)
             if (allSubNodesCompleted)
             {
             {
                 node.OverallStatus = ProcessStatus.Completed;
                 node.OverallStatus = ProcessStatus.Completed;
-
                 process.OverallStatus = ProcessStatus.Completed;
                 process.OverallStatus = ProcessStatus.Completed;
                 process.EndTime = DateTime.Now;
                 process.EndTime = DateTime.Now;
                 process.UpdatedUserId = dto.CurrUserId;
                 process.UpdatedUserId = dto.CurrUserId;
@@ -866,7 +1011,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
             await _sqlSugar.Updateable(node)
             await _sqlSugar.Updateable(node)
                 .UpdateColumns(n => new
                 .UpdateColumns(n => new
                 {
                 {
-                    ActualDone = isDtNul ? node.ActualDone : null,
+                    n.ActualDone,
                     n.IsAssist,
                     n.IsAssist,
                     n.IsFileUp,
                     n.IsFileUp,
                     n.IsPart,
                     n.IsPart,
@@ -875,6 +1020,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
             //记录节点日志
             //记录节点日志
             await LogNodeOpAsync(nodeBefore, node, "Update", currUserId);
             await LogNodeOpAsync(nodeBefore, node, "Update", currUserId);
 
 
+            //当前节点未完成则更改节点状态为已完成
+            if (node.OverallStatus == ProcessStatus.InProgress)
+            {
+                await UpdateNodeStatusAsync(node.Id,dto.CurrUserId);
+            }
+
             return new Result { Code = 200, Msg = "实际操作时间设置成功。" };
             return new Result { Code = 200, Msg = "实际操作时间设置成功。" };
         }
         }
 
 

+ 40 - 5
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/CompanyDailyKpiRepository.cs

@@ -166,9 +166,39 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// 基础数据
         /// 基础数据
         /// </summary>
         /// </summary>
         /// <returns></returns>
         /// <returns></returns>
-        public async Task<JsonView> InitAsync()
+        public async Task<JsonView> InitAsync(int currUserId)
         {
         {
-            var depNames = new List<string> { "财务部", "市场部" };
+            var currUserInfo = await _sqlSugar.Queryable<Sys_Users>()
+                .LeftJoin<Sys_JobPost>((u, jp) => u.JobPostId == jp.Id)
+                .LeftJoin<Sys_Department>((u, jp, d) => u.DepId == d.Id)
+                .LeftJoin<Sys_Company>((u, jp, d, c) => u.CompanyId == c.Id)
+                .Where((u, jp, d, c) => u.IsDel == 0 && u.Id == currUserId)
+                .Select((u, jp, d, c) => new
+                {
+                    UserId = u.Id,
+                    u.CompanyId,
+                    c.CompanyName,
+                    u.DepId,
+                    d.DepName,
+                    u.JobPostId,
+                    jp.JobName,
+                    UserName = u.CnName
+                })
+                .OrderBy(u => u.CompanyId)
+                .FirstAsync();
+            if (currUserInfo == null)
+            {
+                _jv.Msg = $"当前登录用户信息不存在。";
+                return _jv;
+            }
+
+            //验证是否是经理主管 是 可操作保存;是被考核人只能查看自己
+            var isSave = !string.IsNullOrEmpty(currUserInfo.JobName) &&
+                          (currUserInfo.JobName.Contains("总监") ||
+                           currUserInfo.JobName.Contains("经理") ||
+                           currUserInfo.JobName.Contains("主管"));
+
+            var depNames = new List<string> { currUserInfo?.DepName ?? "" };
             var result = await KpiDepartmentsAndJobs(depNames);
             var result = await KpiDepartmentsAndJobs(depNames);
             if (!result.Success)
             if (!result.Success)
             {
             {
@@ -199,9 +229,14 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 .SelectMany(x => x.JobNames)
                 .SelectMany(x => x.JobNames)
                 .ToList();
                 .ToList();
 
 
-            var view = userInfos.Where(x => jobNames.Contains(x.JobName))
-                .Select(x => new KpiTempUserInfo() { Id = x.UserId, DepName = x.DepName, JobName = x.JobName, Name = x.UserName })
-                .ToList();
+            var view = new
+            {
+                isOp = isSave,
+                userInfos = userInfos.Where(x => jobNames.Contains(x.JobName))
+                    .WhereIF(!isSave, x=> x.UserId == currUserId)
+                    .Select(x => new KpiTempUserInfo() { Id = x.UserId, DepName = x.DepName, JobName = x.JobName, Name = x.UserName })
+                    .ToList()
+            };
             _jv.Code = StatusCodes.Status200OK;
             _jv.Code = StatusCodes.Status200OK;
             _jv.Data = view;
             _jv.Data = view;
             _jv.Msg = $"操作成功";
             _jv.Msg = $"操作成功";

+ 39 - 19
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/TaskAllocationRepository.cs

@@ -47,19 +47,19 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// <param name="taskAllocation"></param>
         /// <param name="taskAllocation"></param>
         /// <param name="userId"></param>
         /// <param name="userId"></param>
         /// <returns></returns>
         /// <returns></returns>
-        public TaskOperationAudit TaskOperationAudit(Pm_TaskAllocation taskAllocation, int userId)
+        public TaskOperationPerm TaskOperationAudit(Pm_TaskAllocation taskAllocation, int userId)
         {
         {
-            TaskOperationAudit taskOperationAudit = new TaskOperationAudit();
+            TaskOperationPerm taskOperationPrem = new TaskOperationPerm();
             if (taskAllocation.CreateUserId == userId)
             if (taskAllocation.CreateUserId == userId)
             {
             {
-                taskOperationAudit.TaskAddAudit = 1;
-                taskOperationAudit.TaskDelAudit = 1;
-                taskOperationAudit.TasStopAudit = 1;
-                taskOperationAudit.TaskComfirmAudit = 1;
-                taskOperationAudit.TaskScoreAudit = 1;
+                taskOperationPrem.IsAddPerm = true;
+                taskOperationPrem.IsDelPerm = true;
+                taskOperationPrem.IsStopPerm = true;
+                taskOperationPrem.IsComfirmPerm = true;
+                taskOperationPrem.IsScorePerm = true;
             }
             }
 
 
-            return taskOperationAudit;
+            return taskOperationPrem;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -77,16 +77,19 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 }
                 }
 
 
                 //任务类型
                 //任务类型
-                var taskTypeInfos = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.STid == 127 && x.IsDel == 0)
+                var taskTypeInfos = _sqlSugar.Queryable<Sys_SetData>()
+                    .Where(x => x.STid == 127 && x.IsDel == 0)
                     .Select(x => new ValueInfo { Id = x.Id, Name = x.Name })
                     .Select(x => new ValueInfo { Id = x.Id, Name = x.Name })
                     .ToList();
                     .ToList();
 
 
-                //任务名称
+                //任务名称 
                 var taskNameInfos = _sqlSugar.Queryable<Pm_TaskAllocation, Pm_TaskRelevanceUser>((ta, tau) => new JoinQueryInfos(JoinType.Left, ta.Id == tau.TAId))
                 var taskNameInfos = _sqlSugar.Queryable<Pm_TaskAllocation, Pm_TaskRelevanceUser>((ta, tau) => new JoinQueryInfos(JoinType.Left, ta.Id == tau.TAId))
-                    .Where((ta, tau) => ta.IsDel == 0 && tau.IsDel == 0)
-                    .Where((ta, tau) => ta.CreateUserId == userId || tau.UserId == userId)
-                    .Select(ta => ta.TaskName).ToList()
-                    .Distinct().ToList();
+                    .Where((ta, taru) => ta.IsDel == 0 && taru.IsDel == 0)
+                    .Where((ta, taru) => ta.CreateUserId == userId || taru.UserId == userId)
+                    .OrderByDescending((ta, taru) => ta.CreateTime)
+                    .Select(ta => ta.TaskName)
+                    .Distinct()
+                    .ToList();
 
 
                 //团组名称
                 //团组名称
                 var groupNameInfos = _sqlSugar.Queryable<Grp_DelegationInfo>()
                 var groupNameInfos = _sqlSugar.Queryable<Grp_DelegationInfo>()
@@ -104,7 +107,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
 
                 //执行任务人员信息 1 公司总经理/副总 可分配 所有人的任务 2 公司 部门经理/主管 可分配 部门下的人员的任务
                 //执行任务人员信息 1 公司总经理/副总 可分配 所有人的任务 2 公司 部门经理/主管 可分配 部门下的人员的任务
                 var executeTaskUserInfos = new List<ExecuteTaskUserInfo>();
                 var executeTaskUserInfos = new List<ExecuteTaskUserInfo>();
-                var taskOpertionAudit = new TaskOperationAudit();
+                var taskOpertionAudit = new TaskOperationPerm();
 
 
                 var taskAudits = _sqlSugar.Queryable<Pm_TaskJobRelevancy>().Where(it => it.IsDel == 0 && it.PrimaryUserId == userId).ToList();
                 var taskAudits = _sqlSugar.Queryable<Pm_TaskJobRelevancy>().Where(it => it.IsDel == 0 && it.PrimaryUserId == userId).ToList();
                 var taslPerm = taskAudits.Any();
                 var taslPerm = taskAudits.Any();
@@ -122,9 +125,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     //任务权限
                     //任务权限
                     if (taslPerm)
                     if (taslPerm)
                     {
                     {
-                        taskOpertionAudit.TaskAddAudit = 1;
-                        taskOpertionAudit.TaskDelAudit = 1;
-                        taskOpertionAudit.TasStopAudit = 1;
+                        taskOpertionAudit.IsAddPerm = true;
+                        taskOpertionAudit.IsDelPerm = true;
+                        taskOpertionAudit.IsStopPerm = true;
                     }
                     }
 
 
                     var userIds = taskAudits.Select(it => it.SubUserId).ToList();
                     var userIds = taskAudits.Select(it => it.SubUserId).ToList();
@@ -141,7 +144,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
 
 
                 var view = new InitView()
                 var view = new InitView()
                 {
                 {
-                    TaskOperationAudit = taskOpertionAudit,
+                    OperationPerm = taskOpertionAudit,
                     TaskNameInfos = taskNameInfos,
                     TaskNameInfos = taskNameInfos,
                     ExecuteTaskUserInfos = executeTaskUserInfos,
                     ExecuteTaskUserInfos = executeTaskUserInfos,
                     GroupNameInfos = groupNameInfos,
                     GroupNameInfos = groupNameInfos,
@@ -156,6 +159,23 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             return _result;
             return _result;
         }
         }
 
 
+        /// <summary>
+        /// 任务发布者验证
+        /// </summary>
+        /// <returns></returns>
+        public async Task<(bool isTaskPublisher, List<int> userIds)> ValidateTaskPublisher(int userId)
+        {
+            var taskAudits = await _sqlSugar.Queryable<Pm_TaskJobRelevancy>().Where(it => it.IsDel == 0 && it.PrimaryUserId == userId).ToListAsync();
+            
+            if (taskAudits.Any())
+            {
+                return (true, taskAudits.Select(x => x.SubUserId).ToList());
+            }
+
+            return (false, new List<int>());
+        }
+
+
         /// <summary>
         /// <summary>
         /// 任务指派
         /// 任务指派
         /// 详情
         /// 详情