Browse Source

新增团组费用录入确认功能及代码优化

- 在 Program.cs 中初始化 "团组费用录入通知记录表"。
- 在 GroupsController.cs 中新增 `_dataInit` 字段,优化岗位费用类型初始化逻辑。
- 修复 `GetGroupNamesByUserId` 方法参数命名错误。
- 新增 POST 接口 `FeeEntryAcknowledgeCrate`,支持批量确认团组费用录入记录。
- 在查询团组名称时,新增对已确认团组的过滤条件。
- 新增 `FeeEntryAcknowledgeCrateDto` 数据传输对象。
- 修改 `Grp_FeeEntryAcknowledge` 默认确认方式为 `WebConfirm`。
- 更新枚举值描述,将 `SystemClick` 重命名为 `WebConfirm`。
Lyyyi 19 hours ago
parent
commit
c00f0b81b1

+ 2 - 1
OASystem/EntitySync/Program.cs

@@ -176,6 +176,7 @@ db.CodeFirst.SetStringDefaultLength(50).BackupTable().InitTables(new Type[]
     //typeof(Grp_ProcessOverview),//团组流程总览表
     //typeof(Grp_ProcessNode),//流程节点
     //typeof(Grp_VisaProcessSteps_Log),//流程节点 
-    typeof(Grp_ProcessLog),//流程节点 
+    //typeof(Grp_ProcessLog),//流程节点 
+    typeof(Grp_FeeEntryAcknowledge),//团组费用录入通知记录表 
 });
 Console.WriteLine("数据库结构同步完成!");

+ 144 - 32
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -128,6 +128,33 @@ namespace OASystem.API.Controllers
 
         private readonly IDeepSeekService _deepSeekService;
 
+        /// <summary>
+        ///初始化岗位对应负责的数据类型
+        /// 
+        ///  岗位ID
+        ///  24 机票
+        ///  25 酒店
+        ///  26 签证
+        ///  27 商邀
+        ///  28 OP
+        ///  
+        ///  费用类型ID
+        ///  76 酒店预订	
+        ///  79 车/导游地接	
+        ///  80 签证
+        ///  81 邀请/公务活动
+        ///  82 团组客户保险
+        ///  85 机票预订
+        ///  98 其他款项
+        /// </summary>
+        private readonly Dictionary<int, List<int>> _dataInit = new() {
+                { 24, new List<int> { 85 } },      // 机票 -> 机票预订
+                { 25, new List<int> { 76 } },      // 酒店 -> 酒店预订
+                { 26, new List<int> { 80, 82 } },  // 签证 -> 签证, 团组客户保险
+                { 27, new List<int> { 81 } },      // 地接专员 -> 邀请/公务活动
+                { 28, new List<int> { 79 } }       // 商邀 -> 车/导游地接
+            };
+
         /// <summary>
         /// 构造函数
         /// </summary>
@@ -288,21 +315,20 @@ namespace OASystem.API.Controllers
 
         #region 页面加载弹窗信息
 
-
         /// <summary>
         /// 提示用户录入团组费用信息
         /// 根据用户ID获取分配权限内团组名称
         /// </summary>
-        /// <param name="currUSerId">用户Id</param>
+        /// <param name="currUserId">用户Id</param>
         /// <param name="daysAgo">往前推的天数</param>
         /// <returns></returns>
         [HttpGet]
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        public async Task<IActionResult> GetGroupNamesByUserId(int currUSerId, int daysAgo = 5)
+        public async Task<IActionResult> GetGroupNamesByUserId(int currUserId, int daysAgo = 5)
         {
             var stopwatch = Stopwatch.StartNew();
             var userInfo = await _sqlSugar.Queryable<Sys_Users>()
-                .Where(x => x.Id == currUSerId && x.IsDel == 0)
+                .Where(x => x.Id == currUserId && x.IsDel == 0)
                 .Select(x => new { x.Id, x.JobPostId, x.CnName })
                 .FirstAsync();
 
@@ -312,35 +338,9 @@ namespace OASystem.API.Controllers
             }
 
             var jobId = userInfo.JobPostId;
-            //初始化岗位对应负责的数据类型
-            /*
-             * 岗位ID
-             * 24 机票
-             * 25 酒店
-             * 26 签证
-             * 27 商邀
-             * 28 OP
-             * 
-             * 费用类型ID
-             * 76 酒店预订	
-             * 79 车/导游地接	
-             * 80 签证
-             * 81 邀请/公务活动
-             * 82 团组客户保险
-             * 85 机票预订
-             * 98 其他款项
-             */
-
-            Dictionary<int, List<int>> dataInit = new() {
-                { 24, new List<int> { 85 } },      // 机票 -> 机票预订
-                { 25, new List<int> { 76 } },      // 酒店 -> 酒店预订
-                { 26, new List<int> { 80, 82 } },  // 签证 -> 签证, 团组客户保险
-                { 27, new List<int> { 81 } },      // 地接专员 -> 邀请/公务活动
-                { 28, new List<int> { 79 } }       // 商邀 -> 车/导游地接
-            };
 
             var feeTypeIds = new List<int>() { };
-            if (dataInit.TryGetValue(jobId, out var values))
+            if (_dataInit.TryGetValue(jobId, out var values))
             {
                 feeTypeIds = values;
             }
@@ -354,12 +354,19 @@ namespace OASystem.API.Controllers
             var groupNames = await _sqlSugar.Queryable<Grp_DelegationInfo>()
                 .Where(di => di.IsDel == 0)
                 .Where(di => di.VisitDate >= today_startDate && di.VisitDate <= today_endDate)
+                // 存在任务分配记录
                 .Where(di => SqlFunc.Subqueryable<Grp_GroupsTaskAssignment>()
                     .Where(gta => gta.DIId == di.Id && gta.IsDel == 0 && feeTypeIds.Contains(gta.CTId))
                     .Any())
+                // 不存在费用记录
                 .Where(di => !SqlFunc.Subqueryable<Grp_CreditCardPayment>()
                     .Where(ccp => ccp.DIId == di.Id && ccp.IsDel == 0 && feeTypeIds.Contains(ccp.CTable))
                     .Any())
+                // 新增条件:不在确认记录表中(排除已确认的团组)
+                .Where(di => !SqlFunc.Subqueryable<Grp_FeeEntryAcknowledge>()
+                    .Where(ack => ack.GroupId == di.Id && ack.IsDel == 0 && ack.UserId == currUserId)
+                    .Where(ack => ack.IsAcknowledged == AcknowledgeStatusEnum.Acknowledged) // 只排除已确认的记录
+                    .Any())
                 .Select(di => new
                 {
                     di.Id,
@@ -373,10 +380,115 @@ namespace OASystem.API.Controllers
             return Ok(JsonView(true, $"操作成功!【耗时:{stopwatch.ElapsedMilliseconds}ms】", new
             {
                 isTips = groupNames.Any(),
-                groupNames = groupNames.Select(x => new { x.Id, GroupName = x.TeamName })
+                groupNames = groupNames.Select(x => new { x.Id, GroupName = x.TeamName, x.VisitDate }).ToList()
             }));
         }
 
+        /// <summary>
+        /// 提示用户录入团组费用信息
+        /// 已知晓确认操作记录(添加)
+        /// </summary>
+        /// <param name="dto">请求体</param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> FeeEntryAcknowledgeCrate(FeeEntryAcknowledgeCrateDto dto)
+        {
+            // 1. 参数验证
+            if (dto?.GroupIds == null || !dto.GroupIds.Any())
+            {
+                return Ok(JsonView(false, "请选择需要确认的团组!"));
+            }
+
+            if (dto.GroupIds.Count > 100)
+            {
+                return Ok(JsonView(false, "一次性确认团组数量不能超过100个!"));
+            }
+
+            if (dto.CurrUserId <= 0)
+            {
+                return Ok(JsonView(false, "用户ID无效!"));
+            }
+
+            //2. 验证用户存在性
+            var userInfo = await _sqlSugar.Queryable<Sys_Users>()
+                .Where(x => x.Id == dto.CurrUserId && x.IsDel == 0)
+                .Select(x => new { x.Id, x.JobPostId, x.CnName })
+                .FirstAsync();
+
+            if (userInfo == null)
+            {
+                return Ok(JsonView(false, "用户不存在或已被禁用!"));
+            }
+
+            // 3. 获取费用类型
+            var feeTypeIds = new List<int>() { };
+            if (_dataInit.TryGetValue(userInfo.JobPostId, out var values))
+            {
+                feeTypeIds = values;
+            }
+
+            // 4. 验证团组存在性
+            var validGroupIds = await _sqlSugar.Queryable<Grp_DelegationInfo>()
+                .Where(x => dto.GroupIds.Contains(x.Id) && x.IsDel == 0)
+                .Select(x => x.Id)
+                .ToListAsync();
+
+            if (!validGroupIds.Any())
+            {
+                return Ok(JsonView(false, "未找到有效的团组信息!"));
+            }
+
+            // 5. 检查是否已存在确认记录(避免重复确认)
+            var existingRecords = await _sqlSugar.Queryable<Grp_FeeEntryAcknowledge>()
+                .Where(x => validGroupIds.Contains(x.GroupId) &&
+                           x.UserId == dto.CurrUserId &&
+                           x.IsDel == 0)
+                .Select(x => new { x.GroupId, x.FeeTypeId })
+                .ToListAsync();
+
+            // 6. 准备插入数据(过滤已存在的记录)
+            var infos = new List<Grp_FeeEntryAcknowledge>();
+
+            foreach (var groupId in validGroupIds)
+            {
+                // 为每个费用类型创建确认记录
+                foreach (var feeTypeId in feeTypeIds)
+                {
+                    // 检查是否已存在相同记录
+                    var exists = existingRecords.Any(x => x.GroupId == groupId && x.FeeTypeId == feeTypeId);
+                    if (!exists)
+                    {
+                        infos.Add(new Grp_FeeEntryAcknowledge()
+                        {
+                            GroupId = groupId,
+                            UserId = dto.CurrUserId,
+                            JobPostId = userInfo.JobPostId,
+                            FeeTypeId = feeTypeId,
+                            IsAcknowledged = Domain.Enums.AcknowledgeStatusEnum.Acknowledged,
+                            AcknowledgeTime = DateTime.Now,
+                            AcknowledgeType = Domain.Enums.AcknowledgeTypeEnum.WebConfirm,
+                            CreateUserId = 4, // 系统创建
+                        });
+                    }
+                }
+            }
+
+            if (!infos.Any())
+            {
+                return Ok(JsonView(true, "所选团组已确认,无需重复操作!"));
+            }
+
+            // 7. 批量插入数据
+            var successCount = await _sqlSugar.Insertable(infos).ExecuteCommandAsync();
+            if (successCount < 1)
+            {
+                return Ok(JsonView(false, $"操作失败!"));
+            }
+
+            return Ok(JsonView(true, $"操作成功!"));
+        }
+
         #endregion
 
         #region 流程管控

+ 27 - 0
OASystem/OASystem.Domain/Dtos/Groups/FeeEntryAcknowledgeDtos.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Dtos.Groups
+{
+    public class FeeEntryAcknowledgeDtos
+    {
+    }
+
+    public class FeeEntryAcknowledgeCrateDto
+    {
+
+        /// <summary>
+        /// 人员ID
+        /// </summary>
+        public int CurrUserId { get; set; }
+
+        /// <summary>
+        /// 团组ID
+        /// </summary>
+        public List<int> GroupIds { get; set; }
+        
+    }
+}

+ 2 - 2
OASystem/OASystem.Domain/Entities/Groups/Grp_FeeEntryNotifyRecord.cs

@@ -17,7 +17,7 @@ namespace OASystem.Domain.Entities.Groups
         /// 团组ID
         /// </summary>
         [SugarColumn(ColumnDescription = "团组ID", IsNullable = true, ColumnDataType = "int")]
-        public int GroupId { get; set; }
+        public int GroupId { get; set; }    
 
         /// <summary>
         /// 人员ID
@@ -53,7 +53,7 @@ namespace OASystem.Domain.Entities.Groups
         ///  确认方式:1-系统点击 2-APP确认 3-其他
         /// </summary>
         [SugarColumn(ColumnDescription = "确认方式", IsNullable = true, ColumnDataType = "int")]
-        public AcknowledgeTypeEnum AcknowledgeType { get; set; } = AcknowledgeTypeEnum.SystemClick;
+        public AcknowledgeTypeEnum AcknowledgeType { get; set; } = AcknowledgeTypeEnum.WebConfirm;
 
     }
 }

+ 2 - 2
OASystem/OASystem.Domain/Enums/AcknowledgeStatusEnum.cs

@@ -28,9 +28,9 @@ namespace OASystem.Domain.Enums
     public enum AcknowledgeTypeEnum
     {
         /// <summary>
-        /// 系统点击
+        /// Web确认
         /// </summary>
-        SystemClick = 1,
+        WebConfirm = 1,
 
         /// <summary>
         /// APP确认