Browse Source

优化审核流程和状态管理

在 `PersonnelModuleController.cs` 中,注释掉 `GoodsStorageList` 方法的 `currUserInfo` 参数,并在 `GoodsStorageListDto` 中新增 `CurrUserId` 属性。
在 `GoodsDTO.cs` 中添加 `CurrUserId` 属性以支持用户 ID 的使用。
修改 `Pm_GoodsReceive.cs` 和 `Pm_GoodsStorage.cs` 中的 `StatusDesc` 格式,使用 `<br/>` 标签替代换行符。
在 `GoodsAuditEnum.cs` 中增加多个审核状态描述并更新现有状态的注释。
调整 `GoodsRepository.cs` 中的方法参数和逻辑,增加对当前用户权限的检查,并引入新的审核状态处理逻辑。
在 `GoodsReceiveAudit` 方法中增加审核权限验证,确保在合适的状态下进行审核操作。
在审核相关方法中处理状态描述,确保审核过程中的状态变化被正确记录。
增强出库确认的状态处理逻辑,确保库存和状态描述在出库过程中得到正确更新。
增加对批次库存的管理,确保出库时相关库存信息的正确更新。

这些更改旨在提升系统的可用性和安全性。
LEIYI 2 weeks ago
parent
commit
0c23bd77a6

+ 5 - 3
OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs

@@ -1923,13 +1923,15 @@ WHERE
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
         public async Task<IActionResult> GoodsStorageList(GoodsStorageListDto dto)
         {
-            var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
+            //var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
             //if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
 
             if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
             if (dto.PageIndex < 1 || dto.PageSize < 1) return Ok(JsonView(false, MsgTips.PageIndex));
 
-            return Ok(await _goodsRep.GoodsStorageList(dto, currUserInfo?.UserId ?? 0));
+            return Ok(await _goodsRep.GoodsStorageList(dto));
+            //return Ok(await _goodsRep.GoodsStorageList(dto, 0));
+
         }
 
         /// <summary>
@@ -2080,7 +2082,7 @@ WHERE
                 if (pageFunAuthView.FilesDownloadAuth == 0) return Ok(JsonView(false, "您未分配文件下载权限!"));
                 #endregion
             }
-
+            dto.CurrUserId = currUserInfo.UserId;
             return Ok(await _goodsRep.GoodsReceiveList(dto));
         }
 

+ 5 - 1
OASystem/OASystem.Domain/Dtos/PersonnelModule/GoodsDTO.cs

@@ -92,6 +92,8 @@ namespace OASystem.Domain.Dtos.PersonnelModule
     /// </summary>
     public class GoodsStorageListDto : DtoBase
     {
+        public int CurrUserId { get; set; }
+
         /// <summary>
         /// 物品Id
         /// </summary>
@@ -282,6 +284,8 @@ namespace OASystem.Domain.Dtos.PersonnelModule
         /// 是否导出Excel
         /// </summary>
         public bool IsExcelDownload { get; set; } = false;
+
+        public int CurrUserId { get; set; }
     }
 
     /// <summary>
@@ -353,7 +357,7 @@ namespace OASystem.Domain.Dtos.PersonnelModule
         public string Label { get; set; }
 
         /// <summary>
-        /// 审核状态
+        /// 审核状态 可用状态 1:取消确认、取消拒绝 1:领用确认 2:领用拒绝 3:出库确认、出库拒绝 5:出库确认 6:出库拒绝
         /// </summary>
         public GoodsAuditEnum AuditEnum { get; set; }
     }

+ 7 - 0
OASystem/OASystem.Domain/Entities/PersonnelModule/Pm_GoodsReceive.cs

@@ -65,5 +65,12 @@ namespace OASystem.Domain.Entities.PersonnelModule
         /// </summary>
         [SugarColumn(ColumnDescription = "审核时间", IsNullable = true, ColumnDataType = "datetime")]
         public DateTime AuditTime { get; set; }
+
+        /// <summary>
+        /// 领用/出库确认 状态描述
+        /// </summary>
+        [SugarColumn(ColumnDescription = "领用/出库确认 状态描述", IsNullable = true, ColumnDataType = "varchar(255)")]
+        public string StatusDesc { get; set; } = string.Format("领用确认:状态:待确认  审核人:-  审核时间:-;<br/>人事部:状态:待确认  审核人:-  审核时间:-;<br/>财务部:状态:待确认  审核人:-  审核时间:-;");
+
     }
 }

+ 1 - 1
OASystem/OASystem.Domain/Entities/PersonnelModule/Pm_GoodsStorage.cs

@@ -96,7 +96,7 @@ namespace OASystem.Domain.Entities.PersonnelModule
         /// 入库确认描述
         /// </summary>
         [SugarColumn(ColumnDescription = "入库确认描述", IsNullable = true, ColumnDataType = "varchar(100)")]
-        public string StatusDesc { get; set; } = string.Format("人事部:状态:待确认\t审核人:-\t审核时间:-;\r\n财务部:状态:待确认\t审核人:-\t审核时间:-;");
+        public string StatusDesc { get; set; } = string.Format("人事部:状态:待确认  审核人:-  审核时间:-;<br/>财务部:状态:待确认  审核人:-  审核时间:-;");
 
     }
 }

+ 34 - 10
OASystem/OASystem.Domain/Enums/GoodsAuditEnum.cs

@@ -12,22 +12,46 @@ namespace OASystem.Domain.Enums
     /// </summary>
     public enum GoodsAuditEnum :int
     {
+        /*
+         * 审核流程 1 领用待确认 2 领用已确认 3 领用确认已拒绝 4 出库待确认 5 出库确认中 6 出库确认完成 7 出库确认拒绝
+         * 
+         */
+
         /// <summary>
-        /// 待审核
+        /// 领用待确认
         /// </summary>
-        [Description("待审核")]
+        [Description("领用待确认")]
         Pending,
         /// <summary>
-        /// 已通过审核
+        /// 领用已确认
         /// </summary>
-        [Description("已通过")]
+        [Description("领用已确认")]
         Approved,
         /// <summary>
-        /// 已拒绝审核
+        /// 领用确认已拒绝
         /// </summary>
-        [Description("未通过")]
-        UnApproved
-
+        [Description("领用已拒绝")]
+        UnApproved,
+        /// <summary>
+        /// 出库待确认
+        /// </summary>
+        [Description("出库待确认")]
+        OutPending,
+        /// <summary>
+        /// 出库确认中
+        /// </summary>
+        [Description("出库确认中")]
+        OutConfirming,
+        /// <summary>
+        /// 出库确认完成
+        /// </summary>
+        [Description("出库确认完成")]
+        OutConfirmed,
+        /// <summary>
+        /// 出库确认拒绝
+        /// </summary>
+        [Description("出库确认拒绝")]
+        OutRejected,
     }
 
     /// <summary>
@@ -41,9 +65,9 @@ namespace OASystem.Domain.Enums
         [Description("待确认")]
         WaitConfirm,
         /// <summary>
-        /// 部分确认
+        /// 确认
         /// </summary>
-        [Description("部分确认")]
+        [Description("确认")]
         PartConfirmed,
         /// <summary>
         /// 已确认

+ 4 - 1
OASystem/OASystem.Domain/ViewModels/PersonnelModule/GoodsInfoView.cs

@@ -181,7 +181,6 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
 
     public class GoodsReceiveView
     {
-
         public int Id { get; set; }
         public int GroupId { get; set; }
         public int GoodsId { get; set; }
@@ -192,6 +191,7 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
         public string Remark { get; set; }
         public GoodsAuditEnum AuditStatus { get; set; }
         public string AuditStatusText { get { return AuditStatus.GetEnumDescription(); } }
+        public string StatusDesc { get; set; }
         public int AuditUserId { get; set; }
         public string AuditUserName { get; set; }
         public DateTime AuditTime { get; set; }
@@ -204,6 +204,7 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
     public class GoodsReceiveListView: GoodsReceiveView
     {
         public string GoodsType { get; set; }
+        public GoodsStorageAuditPerView[] AuditPers { get; set; }
     }
 
     public class GoodsReceiveListMobileView : GoodsReceiveListView
@@ -286,6 +287,8 @@ namespace OASystem.Domain.ViewModels.PersonnelModule
         public string StatusDesc { get; set; }
         public DateTime CreateTime { get; set; }
 
+        public string Remark { get; set; }
+
         public GoodsStorageAuditPerView[] AuditPers { get; set; }
 
     }

+ 674 - 83
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/GoodsRepository.cs

@@ -4,6 +4,7 @@ using Aspose.Words.Drawing;
 using AutoMapper;
 using EyeSoft.IO;
 using EyeSoft.Reflection;
+using EyeSoft.Runtime.InteropServices;
 using Newtonsoft.Json;
 using NPOI.OpenXmlFormats.Vml;
 using NPOI.SS.UserModel;
@@ -128,10 +129,17 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 }
             }
 
+            var auditEnums = new List<GoodsAuditEnum>() {
+                GoodsAuditEnum.Pending,
+                GoodsAuditEnum.OutPending,
+                GoodsAuditEnum.OutConfirming
+            };
+
             RefAsync<int> total = 0;
 
             var data = await _sqlSugar.Queryable<GoodsListView>()
-                .Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && z1.AuditStatus == GoodsAuditEnum.Pending).ToList())
+                //.Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && z1.AuditStatus == GoodsAuditEnum.Pending).ToList())
+                .Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && auditEnums.Contains(z1.AuditStatus)).ToList())
                 .Includes(glv => glv.TypeData)
                 .Includes(glv => glv.UserData)
                 .LeftJoin<Sys_SetData>((glv, sd) => glv.Type == sd.Id)
@@ -142,7 +150,6 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 .OrderByDescending(glv => glv.LastUpdateTime)
                 .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
 
-
             var view = data.Select(x => new
             {
                 x.Id,
@@ -323,11 +330,11 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        public async Task<JsonView> GoodsStorageList(GoodsStorageListDto dto,int userId)
+        public async Task<JsonView> GoodsStorageList(GoodsStorageListDto dto)
         {
-
             string reqAuditLabel = dto.AuditLabel;
             var auditLabel = Array.Empty<int>();
+            int userId = dto.CurrUserId;
 
             if (!string.IsNullOrEmpty(reqAuditLabel))
             {
@@ -373,6 +380,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     ConfirmStatus = gs.ConfirmStatus,
                     StatusDesc = gs.StatusDesc,
                     CreateTime = gs.CreateTime,
+                    Remark = gs.Remark
                 })
                 .OrderByDescending(gs => gs.CreateTime)
                 .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
@@ -659,7 +667,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                        auditStatus = preInfo.AuditStatus.GetEnumDescription(),
                        auditUserName = preInfo.AuditUserId > 0 ? _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == preInfo.AuditUserId)?.CnName ?? "-" : "-",
                        auditTime = preInfo.AuditUserId > 0 ? preInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";
-                statusDesc.AppendLine(string.Format("{0}:状态:{1}\t审核人:{2}\t审核时间:{3};", depName, auditStatus, auditUserName, auditTime));
+                statusDesc.Append(string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>", depName, auditStatus, auditUserName, auditTime));
             }
 
             //更改入库状态及描述
@@ -1031,6 +1039,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                   userLabel = Array.Empty<int>(),
                   auditLabel = Array.Empty<int>(),
                   groupLabel = Array.Empty<int>();
+            int currUserId = dto.CurrUserId;
             if (!string.IsNullOrEmpty(dto.TypeLabel))
             {
                 typeLabel = dto.TypeLabel
@@ -1111,7 +1120,7 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     Reason = gr.Reason,
                     Remark = gr.Remark,
                     AuditStatus = gr.AuditStatus,
-                    //AuditStatusText = gr.AuditStatus.GetEnumDescription(),
+                    StatusDesc = gr.StatusDesc,
                     AuditUserId = gr.AuditUserId,
                     AuditUserName = u1.CnName,
                     AuditTime = gr.AuditTime,
@@ -1119,7 +1128,6 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     CreateTime = gr.CreateTime
                 })
                 .OrderByDescending(gr => gr.CreateTime);
-                                     
 
             //excel导出
             if (dto.IsExcelDownload)
@@ -1161,13 +1169,45 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
             
             //返回分页数据
             var view = await data.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+
+            //财务人事审核权限处理
+            var auditList = GoodsStorageConfirmAuditDep(2);
+            bool hrAuditPer = false,
+                 finAuditPer = false;
+            var hrAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Hr);
+            var finAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Financial);
+            if (hrAuditInfo != null)
+            {
+                if (hrAuditInfo.AuditorIds.Any(x => x == currUserId))
+                {
+                    hrAuditPer = true;
+                }
+            }
+            if (finAuditInfo != null)
+            {
+                if (finAuditInfo.AuditorIds.Any(x => x == currUserId))
+                {
+                    finAuditPer = true;
+                }
+            }
+            foreach (var item in view)
+            {
+                item.AuditPers = new GoodsStorageAuditPerView[] {
+                    new (){ AuditPer  = hrAuditPer, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetEnumDescription()},
+                    new (){ AuditPer  = finAuditPer, AuditDep = GoodsAuditDepEnum.Financial, ButtonText = GoodsAuditDepEnum.Financial.GetEnumDescription()}
+                };
+            }
+
             if (dto.PortType == 2 || dto.PortType == 3)
             {
                 _jv.Data = view;
             }
             else if (dto.PortType == 1)
             {
-                _jv.Data = _mapper.Map<List<GoodsReceiveListView>>(view);
+                var view1 = _mapper.Map<List<GoodsReceiveListView>>(view);
+
+
+                _jv.Data = view1;
             }
 
             _jv.Code = StatusCodes.Status200OK;
@@ -1270,30 +1310,33 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         {
             var info = _mapper.Map<Pm_GoodsReceive>(dto);
             info.CreateUserId = currUserId;
+
+            var auditEnums = new List<GoodsAuditEnum>() {
+                    GoodsAuditEnum.Approved,    // 1
+                    GoodsAuditEnum.UnApproved,  // 2
+                    GoodsAuditEnum.OutConfirmed,// 5
+                    GoodsAuditEnum.OutRejected  // 6
+                };
+
             _sqlSugar.BeginTran();
 
             //物品现有库存
-            var stockQuantity = _sqlSugar
-                .Queryable<Pm_GoodsInfo>()
-                .First(x => x.Id == info.GoodsId)
-                ?.StockQuantity;
+            var stockQuantity = _sqlSugar.Queryable<Pm_GoodsInfo>().First(x => x.Id == info.GoodsId)?.StockQuantity;
 
             //待审核 该物品数量
-            var waitAuditQuantity = await _sqlSugar
-                .Queryable<Pm_GoodsReceive>()
-                .Where(x => x.IsDel == 0 &&
+            var waitAuditQuantity = await _sqlSugar.Queryable<Pm_GoodsReceive>().Where(x => x.IsDel == 0 &&
                             x.GoodsId == dto.GoodsId &&
-                            x.AuditStatus == GoodsAuditEnum.Pending
-                )
-                .SumAsync(x => x.Quantity);
+                            !auditEnums.Contains(x.AuditStatus)
+                ).SumAsync(x => x.Quantity);
+
             if (info.Id > 0) //修改
             {
                 //审核验证
                 var selectInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.Id == info.Id);
-                if (selectInfo.AuditStatus == GoodsAuditEnum.Approved)
+                if (auditEnums.Contains(selectInfo.AuditStatus))
                 {
                     _sqlSugar.RollbackTran();
-                    _jv.Msg = $"该条数据已通过审核,不可更改!";
+                    _jv.Msg = $"该条数据已执行操作({selectInfo.AuditStatus.GetEnumDescription()}),不可更改!";
                     return _jv;
                 }
 
@@ -1335,14 +1378,28 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                     return _jv;
                 }
 
-                var add = await _sqlSugar.Insertable(info).ExecuteCommandAsync();
-                if (add > 0)
+                var add = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync();
+                if (add < 1)
                 {
-                    _sqlSugar.CommitTran();
-                    _jv.Msg = $"操作成功!";
-                    _jv.Code = StatusCodes.Status200OK;
+                    _sqlSugar.RollbackTran();
+                    _jv.Msg = $"添加失败!";
+                    _jv.Code = StatusCodes.Status400BadRequest;
                     return _jv;
                 }
+
+                //出库确认默认审核状态
+                var goodsAuditList = new List<Pm_GoodsAudit>() {
+                    new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr, add, GoodsConfirmEnum.WaitConfirm, currUserId),
+                    new Pm_GoodsAudit(2, GoodsAuditDepEnum.Financial, add, GoodsConfirmEnum.WaitConfirm, currUserId)
+                };
+                if (goodsAuditList.Any())
+                {
+                    await _sqlSugar.Insertable(goodsAuditList).ExecuteCommandAsync();
+                }
+                _sqlSugar.CommitTran();
+                _jv.Msg = $"操作成功!";
+                _jv.Code = StatusCodes.Status200OK;
+                return _jv;
             }
             _sqlSugar.RollbackTran();
             return _jv;
@@ -1359,50 +1416,342 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
         {
             if (idArray.Length < 1) return _jv;
 
-            //TODO: 审核权限验证
+            var auditEnums = new List<GoodsAuditEnum>() {
+                GoodsAuditEnum.Pending,
+                GoodsAuditEnum.Approved,
+                GoodsAuditEnum.UnApproved,
+                GoodsAuditEnum.OutPending,
+                GoodsAuditEnum.OutConfirmed,
+                GoodsAuditEnum.OutRejected,
+            };
+
+            if (!auditEnums.Contains(auditEnum))
+            {
+                _jv.Msg = $"出库确认状态超出可用范围!";
+                return _jv;
+            }
+
+
+            int receiveId = idArray[0];
+
+            //验证审核部门 审核状态 大于等于 OutPending 时 验证
+            var auditDep = GoodsAuditDepEnum.Hr;
+            if (auditEnum >= GoodsAuditEnum.OutPending)
+            {
+                var auditList = GoodsStorageConfirmAuditDep(2);
+                var auditDepInfo = auditList.Find(x => x.AuditorIds.Contains(userId));
+                if (auditDepInfo == null)
+                {
+                    _jv.Msg = string.Format("未分配出库确认权限!");
+                    return _jv;
+                }
+
+                auditDep = auditDepInfo.AuditDep;
+            }
+
+            var currUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == userId)?.CnName ?? "-";
 
             _sqlSugar.BeginTran();
-            var receiveInfos = await _sqlSugar
+            var receiveInfo = await _sqlSugar
                 .Queryable<Pm_GoodsReceive>()
-                .Where(x => x.IsDel == 0 && idArray.Contains(x.Id))
+                //.Where(x => x.IsDel == 0 && idArray.Contains(x.Id))
+                .Where(x => x.IsDel == 0 && receiveId == x.Id )
+                .FirstAsync();
+
+            if (receiveInfo == null)
+            {
+                _sqlSugar.RollbackTran();
+                _jv.Msg = $"当前领用信息不存在!";
+                return _jv;
+            }
+
+            //审核前状态
+            var preChangeStatus = receiveInfo.AuditStatus;
+
+            //状态验证
+            //if (preChangeStatus == auditEnum)
+            //{
+            //    _sqlSugar.RollbackTran();
+            //    _jv.Msg = $"该条数据状态已设置,不可重复设置!";
+            //    return _jv;
+            //}
+
+            StringBuilder statusDesc = new StringBuilder();
+            //string.Format("领用确认:状态:待确认  审核人:-  审核时间:-;<br/>人事部:状态:待确认  审核人:-  审核时间:-;<br/>财务部:状态:待确认  审核人:-  审核时间:-;");
+            switch (auditEnum)
+            {
+                case GoodsAuditEnum.Pending: //领用待确认(取消确认、取消拒绝)
+                    _jv = await GoodsReceivePending(preChangeStatus, receiveId, userId, currUserName, auditEnum);
+                    break;
+                case GoodsAuditEnum.Approved: //领用确认
+                    _jv = await GoodsReceiveApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum);
+                    break;
+                case GoodsAuditEnum.UnApproved: //领用拒绝
+                    _jv = await GoodsReceiveUnApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum);
+                    break;
+                case GoodsAuditEnum.OutPending: //出库待确认(出库确认、出库拒绝)
+                    _jv = await GoodsReceiveOutPending(preChangeStatus, receiveInfo, userId, auditDep, auditEnum);
+                    break;
+                case GoodsAuditEnum.OutConfirmed: //出库确认
+                    _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum);
+                    break;
+                case GoodsAuditEnum.OutRejected:  //出库拒绝
+                    _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum);
+                    break;
+            }
+
+            if (_jv.Code == StatusCodes.Status200OK)
+            {
+                _sqlSugar.CommitTran();
+                _jv.Msg = $"操作成功!";
+                return _jv;
+            }
+
+            _sqlSugar.RollbackTran();
+            return _jv;
+        }
+
+        /// <summary>
+        /// 物品领用状态 - 领用待确认(取消确认、取消拒绝)
+        /// </summary>
+        /// <param name="preChangeStatus">更改前状态</param>
+        /// <param name="receiveId"></param>
+        /// <param name="userId"></param>
+        /// <param name="userName"></param>
+        /// <param name="auditEnum"></param>
+        /// <returns></returns>
+        public async Task<JsonView> GoodsReceivePending(GoodsAuditEnum preChangeStatus,int receiveId, int userId, string userName, GoodsAuditEnum auditEnum)
+        {
+            _jv.Code = StatusCodes.Status400BadRequest;
+            //领用待确认 操作范围
+            var audirEnumPers = new List<GoodsAuditEnum>() {
+                GoodsAuditEnum.Approved,
+                GoodsAuditEnum.UnApproved
+            };
+
+            if (!audirEnumPers.Contains(preChangeStatus))
+            {
+                _jv.Msg = $"{GoodsAuditEnum.Approved.GetEnumDescription()}、{GoodsAuditEnum.UnApproved.GetEnumDescription()},状态下可取消操作!";
+                return _jv;
+            }
+
+            var currUserOpDt = DateTime.Now;
+            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");
+            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部确认:状态:待确认  审核人:-  审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime);
+            auditEnum = GoodsAuditEnum.Pending;
+            var changeStatus = await _sqlSugar
+                .Updateable<Pm_GoodsReceive>()
+                .SetColumns(x => new Pm_GoodsReceive()
+                {
+                    AuditStatus = auditEnum,
+                    AuditUserId = userId,
+                    AuditTime = currUserOpDt,
+                    StatusDesc = statusDesc
+                })
+                .Where(x => x.Id == receiveId)
+                .ExecuteCommandAsync();
+
+            if (changeStatus > 0)
+            {
+                _jv.Code = StatusCodes.Status200OK;
+            }
+
+            return _jv;
+        }
+
+        /// <summary>
+        /// 物品领用状态 - 领用确认
+        /// </summary>
+        /// <param name="preChangeStatus">更改前状态</param>
+        /// <param name="receiveId"></param>
+        /// <param name="userId"></param>
+        /// <param name="userName"></param>
+        /// <param name="auditEnum"></param>
+        /// <returns></returns>
+        public async Task<JsonView> GoodsReceiveApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId,string userName, GoodsAuditEnum auditEnum)
+        {
+            _jv.Code = StatusCodes.Status400BadRequest;
+            if (preChangeStatus != GoodsAuditEnum.Pending)
+            {
+                _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!";
+                return _jv;
+            }
+
+            var currUserOpDt = DateTime.Now;
+            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");
+            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部确认:状态:待确认  审核人:-  审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime);
+            auditEnum = GoodsAuditEnum.OutPending;
+            var changeStatus = await _sqlSugar
+                .Updateable<Pm_GoodsReceive>()
+                .SetColumns(x => new Pm_GoodsReceive()
+                {
+                    AuditStatus = auditEnum,
+                    AuditUserId = userId,
+                    AuditTime = currUserOpDt,
+                    StatusDesc = statusDesc
+                })
+                .Where(x => x.Id == receiveId)
+                .ExecuteCommandAsync();
+
+            if (changeStatus > 0)
+            {
+                _jv.Code = StatusCodes.Status200OK;
+            }
+
+            return _jv;
+        }
+
+        /// <summary>
+        /// 物品领用状态 - 领用拒绝
+        /// </summary>
+        /// <param name="preChangeStatus">更改前状态</param>
+        /// <param name="receiveId"></param>
+        /// <param name="userId"></param>
+        /// <param name="userName"></param>
+        /// <param name="auditEnum"></param>
+        /// <returns></returns>
+        public async Task<JsonView> GoodsReceiveUnApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum)
+        {
+            _jv.Code = StatusCodes.Status400BadRequest;
+            if (preChangeStatus != GoodsAuditEnum.Pending)
+            {
+                _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!";
+                return _jv;
+            }
+            auditEnum = GoodsAuditEnum.UnApproved;
+            var currUserOpDt = DateTime.Now;
+            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");
+            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部认:状态:待确认  审核人:-  审核时间:-;<br/>", auditEnum.GetEnumDescription(), userName, currUserOpTime);
+
+            var changeStatus = await _sqlSugar
+                .Updateable<Pm_GoodsReceive>()
+                .SetColumns(x => new Pm_GoodsReceive()
+                {
+                    AuditStatus = auditEnum,
+                    AuditUserId = userId,
+                    AuditTime = currUserOpDt,
+                    StatusDesc = statusDesc
+                })
+                .Where(x => x.Id == receiveId)
+                .ExecuteCommandAsync();
+
+            if (changeStatus > 0)
+            {
+                _jv.Code = StatusCodes.Status200OK;
+            }
+
+            return _jv;
+        }
+
+        /// <summary>
+        /// 物品领用状态 - 出库待确认(出库确认、出库拒绝)
+        /// </summary>
+        /// <param name="preChangeStatus">更改前状态</param>
+        /// <param name="receiveId"></param>
+        /// <param name="userId"></param>
+        /// <param name="userName"></param>
+        /// <param name="auditEnum"></param>
+        /// <returns></returns>
+        public async Task<JsonView> GoodsReceiveOutPending(GoodsAuditEnum preChangeStatus, Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum)
+        {
+            _jv.Code = StatusCodes.Status400BadRequest;
+            //出库待确认 操作范围
+            var audirEnumPers = new List<GoodsAuditEnum>() {
+                GoodsAuditEnum.OutConfirmed,
+                GoodsAuditEnum.OutRejected
+            };
+
+            if (!audirEnumPers.Contains(preChangeStatus))
+            {
+                _jv.Msg = $"{GoodsAuditEnum.OutConfirmed.GetEnumDescription()}、{GoodsAuditEnum.OutRejected.GetEnumDescription()},状态下可取消操作!";
+                return _jv;
+            }
+
+            var currUserOpDt = DateTime.Now;
+            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");
+
+            var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>()
+                .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2)
                 .ToListAsync();
 
-            var status = true;
-            foreach (var id in idArray)
+            auditEnum = GoodsAuditEnum.OutPending;
+
+            var auditStatus = GoodsConfirmEnum.WaitConfirm;
+
+            var auditInfo = auditInfos.Find(x => x.Dep == depEnum);
+            if (auditInfo == null)
+            {
+                auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId);
+                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();
+                if (addStatus < 1)
+                {
+                    _jv.Msg = $"出库确认取消操作失败!";
+                    return _jv;
+                }
+                auditInfos.Add(auditInfo);
+            }
+            else
             {
-                //1.更改审核状态
-                var currInfo = receiveInfos.Find(x => x.Id == id);
-                if (currInfo == null) continue;
-                var edit = await _sqlSugar
-                    .Updateable<Pm_GoodsReceive>()
-                    .SetColumns(x => new Pm_GoodsReceive()
+                //移除旧数据
+                auditInfos.Remove(auditInfo);
+                auditInfo.AuditStatus = auditStatus;
+                auditInfo.AuditUserId = userId;
+                auditInfo.AuditTime = currUserOpDt;
+                var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()
+                    .SetColumns(x => new Pm_GoodsAudit()
                     {
-                        AuditStatus = auditEnum,
+                        AuditStatus = auditStatus,
                         AuditUserId = userId,
-                        AuditTime = DateTime.Now,
+                        AuditTime = currUserOpDt
                     })
-                    .Where(x => x.Id == id)
+                    .Where(x => x.Id == auditInfo.Id)
                     .ExecuteCommandAsync();
-                if (edit < 1) status = false;
 
-                //if (auditEnum != GoodsAuditEnum.Approved) continue;
-                //2.更改库存
-                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == currInfo.GoodsId).FirstAsync();
-                if (auditEnum == GoodsAuditEnum.Pending) 
+                if (updStatus < 1)
                 {
-                    goodsInfo.StockQuantity += currInfo.Quantity;
-                    goodsInfo.OQ_Total -= currInfo.Quantity;
+                    _jv.Msg = $"出库确认操作失败!";
+                    return _jv;
                 }
-                else if (auditEnum == GoodsAuditEnum.Approved)
+
+                //添加更新后的数据
+                auditInfos.Add(auditInfo);
+            }
+
+            //处理状态描述
+            StringBuilder statusDesc = new StringBuilder();
+
+            var receiveUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-";
+            string receiveStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",
+                       "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss"));
+            statusDesc.Append(receiveStatusDesc);
+            foreach (var auditInf in auditInfos)
+            {
+                string userName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-";
+                string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";
+                string auditInfStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",
+                       auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime);
+                statusDesc.Append(auditInfStatusDesc);
+            }
+
+            //批次库存信息
+            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;
+
+            //出库确认取消是单独处理
+            if (preChangeStatus == GoodsAuditEnum.OutConfirming)
+            {
+                if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1)
                 {
-                    goodsInfo.StockQuantity -= currInfo.Quantity;
-                    goodsInfo.OQ_Total += currInfo.Quantity;
-                }else if(auditEnum == GoodsAuditEnum.UnApproved) continue;
+                    auditEnum = GoodsAuditEnum.OutConfirming;
+                }
+                    //2.1 更改库存
+                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();
+                goodsInfo.StockQuantity -= receiveInfo.Quantity;
+                goodsInfo.OQ_Total += receiveInfo.Quantity;
                 goodsInfo.LastUpdateTime = DateTime.Now;
                 goodsInfo.LastUpdateUserId = userId;
 
                 var editGoods = await _sqlSugar
-                    .Updateable<Pm_GoodsInfo>(goodsInfo)
+                    .Updateable(goodsInfo)
                     .UpdateColumns(x => new
                     {
                         x.StockQuantity,
@@ -1410,35 +1759,255 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                         x.LastUpdateUserId,
                         x.LastUpdateTime,
                     })
-                    .Where(x => x.Id == currInfo.GoodsId)
+                    .Where(x => x.Id == receiveInfo.GoodsId)
                     .ExecuteCommandAsync();
 
-                if (editGoods < 1) status = false;
+                if (editGoods < 1)
+                {
+                    _jv.Msg = $"库存更新失败!";
+                    return _jv;
+                }
 
-                //3.入库批次关联领用人 更改批次库存
+                //2.2 入库批次关联领用人 更改批次库存
                 var goodsStorages = await _sqlSugar
                     .Queryable<Pm_GoodsStorage>()
                     .Where(x => x.IsDel == 0 &&
-                                x.GoodsId == currInfo.GoodsId &&
+                                x.GoodsId == receiveInfo.GoodsId &&
                                 (x.Quantity - x.ReceiveQuantity) > 0
                         )
                     .OrderBy(x => x.CreateTime)
                     .ToListAsync();
+
                 var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();
                 var batchStorageInfos = new List<Pm_GoodsStorage>();
                 var receiveQuantity = 0.00M; //领用总数量
-                if (auditEnum == GoodsAuditEnum.Approved)
+                foreach (var storage in goodsStorages)
+                {
+                    if (receiveInfo.Quantity == receiveQuantity) break;
+
+                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;
+                    if (thisBatchSurplusQuantity <= 0.00M) continue;
+
+                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量
+                    const decimal unit = 0.50M;
+                    while (receiveQuantity < receiveInfo.Quantity)
+                    {
+                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;
+
+                        thisBatchReceiveQuantity += unit;
+                        receiveQuantity += unit;
+                    }
+                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView
+                    {
+                        StorageId = storage.Id,
+                        Quantity = thisBatchReceiveQuantity
+                    });
+                    storage.ReceiveQuantity += thisBatchReceiveQuantity;
+                    var storageUpd = storage;
+                    //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;
+                    batchStorageInfos.Add(storageUpd);
+                }
+
+                //2.2.1 更改批次库存
+                if (goodsReceiveInfos.Count > 0)
+                {
+                    var edit1 = await _sqlSugar.Updateable(batchStorageInfos)
+                        .UpdateColumns(x => x.ReceiveQuantity)
+                        .WhereColumns(x => x.Id)
+                        .ExecuteCommandAsync();
+                    if (edit1 < 1)
+                    {
+                        _jv.Msg = $"批次库存更新失败!";
+                        return _jv;
+                    }
+                }
+
+                //2.2.2 添加入库批次关联领用人
+                if (goodsReceiveInfos.Count > 0)
+                {
+                    goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);
+                }
+            }
+
+            var statusDesc1 = statusDesc.ToString();
+            var changeStatus = await _sqlSugar
+                .Updateable<Pm_GoodsReceive>()
+                .SetColumns(x => new Pm_GoodsReceive()
+                {
+                    AuditStatus = auditEnum,
+                    StatusDesc = statusDesc1,
+                    GoodsStorageInfo= goodsStorageInfo
+                })
+                .Where(x => x.Id == receiveInfo.Id)
+                .ExecuteCommandAsync();
+
+            if (changeStatus > 0)
+            {
+                _jv.Code = StatusCodes.Status200OK;
+            }
+
+            return _jv;
+        }
+
+        /// <summary>
+        /// 物品领用状态 - 出库确认中、出库确认完成、出库确认拒绝
+        /// </summary>
+        /// <param name="receiveInfo"></param>
+        /// <param name="userId"></param>
+        /// <param name="depEnum"></param>
+        /// <param name="auditEnum"></param>
+        /// <returns></returns>
+        public async Task<JsonView> GoodsReceiveOutConfirming(Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum,GoodsAuditEnum auditEnum)
+        {
+            _jv.Code = StatusCodes.Status400BadRequest;
+
+            if (auditEnum < GoodsAuditEnum.OutPending)
+            {
+                _jv.Msg = $"领用确认执行成功!才可执行出库确认或出库拒绝操作!";
+                return _jv;
+            }
+
+            var currUserOpDt = DateTime.Now;
+            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");
+           
+            var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>()
+                .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2)
+                .ToListAsync();
+
+            var auditStatus = GoodsConfirmEnum.WaitConfirm;
+            if (auditEnum == GoodsAuditEnum.OutRejected) auditStatus = GoodsConfirmEnum.UnApproved;
+            else if (auditEnum == GoodsAuditEnum.OutConfirmed) auditStatus = GoodsConfirmEnum.Confirmed;
+
+            var auditInfo = auditInfos.Find(x => x.Dep == depEnum);
+
+            if (auditInfo == null)
+            {
+                auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId);
+                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();
+                if (addStatus < 1)
+                {
+                    _jv.Msg = $"出库确认操作失败!";
+                    return _jv;
+                }
+                auditInfos.Add(auditInfo);
+            }
+            else
+            {
+                //移除旧数据
+                auditInfos.Remove(auditInfo);
+                auditInfo.AuditStatus = auditStatus;
+                auditInfo.AuditUserId = userId;
+                auditInfo.AuditTime = currUserOpDt;
+                var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()
+                    .SetColumns(x => new Pm_GoodsAudit()
+                    {
+                        AuditStatus = auditStatus,
+                        AuditUserId = userId,
+                        AuditTime = currUserOpDt
+                    })
+                    .Where(x => x.Id == auditInfo.Id)
+                    .ExecuteCommandAsync();
+
+                if (updStatus < 1)
+                {
+                    _jv.Msg = $"出库确认操作失败!";
+                    return _jv;
+                }
+
+                //添加更新后的数据
+                auditInfos.Add(auditInfo);
+            }
+
+            //处理状态描述
+            StringBuilder statusDesc= new StringBuilder();
+
+            var receiveUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-";
+            string receiveStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",
+                       "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss"));
+            statusDesc.Append(receiveStatusDesc);
+            foreach (var auditInf in auditInfos)
+            {
+                string userName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-";
+                string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";
+                string auditInfStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",
+                       auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime);
+                statusDesc.Append(auditInfStatusDesc);
+            }
+
+            //更改前状态
+            var preChangeStatus = receiveInfo.AuditStatus;
+
+            if (preChangeStatus == auditEnum)
+            {
+                _jv.Msg = $"此操作已执行,不可重复操作!";
+                return _jv;
+            }
+
+            //批次库存信息
+            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;
+
+            //更改领用状态及库存
+            if (auditInfos.Any(x => x.AuditStatus == GoodsConfirmEnum.UnApproved))
+            {
+                //出库确认拒绝
+                auditEnum = GoodsAuditEnum.OutRejected;
+            }
+            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 2)
+            {
+                //1.出库确认完成
+                auditEnum = GoodsAuditEnum.OutConfirmed;
+
+                //2.更改前的状态为出库确认中 且 更改后的状态为出库确认完成 执行库存减操作
+                if (preChangeStatus == GoodsAuditEnum.OutConfirming || preChangeStatus == GoodsAuditEnum.OutRejected)
                 {
+                    //2.1 更改库存
+                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();
+                    goodsInfo.StockQuantity -= receiveInfo.Quantity;
+                    goodsInfo.OQ_Total += receiveInfo.Quantity;
+                    goodsInfo.LastUpdateTime = DateTime.Now;
+                    goodsInfo.LastUpdateUserId = userId;
+
+                    var editGoods = await _sqlSugar
+                        .Updateable(goodsInfo)
+                        .UpdateColumns(x => new
+                        {
+                            x.StockQuantity,
+                            x.OQ_Total,
+                            x.LastUpdateUserId,
+                            x.LastUpdateTime,
+                        })
+                        .Where(x => x.Id == receiveInfo.GoodsId)
+                        .ExecuteCommandAsync();
+
+                    if (editGoods < 1)
+                    {
+                        _jv.Msg = $"库存更新失败!";
+                        return _jv;
+                    }
+
+                    //2.2 入库批次关联领用人 更改批次库存
+                    var goodsStorages = await _sqlSugar
+                        .Queryable<Pm_GoodsStorage>()
+                        .Where(x => x.IsDel == 0 &&
+                                    x.GoodsId == receiveInfo.GoodsId &&
+                                    (x.Quantity - x.ReceiveQuantity) > 0
+                            )
+                        .OrderBy(x => x.CreateTime)
+                        .ToListAsync();
+
+                    var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();
+                    var batchStorageInfos = new List<Pm_GoodsStorage>();
+                    var receiveQuantity = 0.00M; //领用总数量
                     foreach (var storage in goodsStorages)
                     {
-                        if (currInfo.Quantity == receiveQuantity) break;
+                        if (receiveInfo.Quantity == receiveQuantity) break;
 
                         var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;
                         if (thisBatchSurplusQuantity <= 0.00M) continue;
 
                         var thisBatchReceiveQuantity = 0.00M; //此批次领用数量
                         const decimal unit = 0.50M;
-                        while (receiveQuantity < currInfo.Quantity)
+                        while (receiveQuantity < receiveInfo.Quantity)
                         {
                             if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;
 
@@ -1455,64 +2024,86 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                         //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;
                         batchStorageInfos.Add(storageUpd);
                     }
-                    //3.1 更改批次库存
+                    
+                    //2.2.1 更改批次库存
                     if (goodsReceiveInfos.Count > 0)
                     {
                         var edit1 = await _sqlSugar.Updateable(batchStorageInfos)
                             .UpdateColumns(x => x.ReceiveQuantity)
                             .WhereColumns(x => x.Id)
                             .ExecuteCommandAsync();
-                        if (edit1 < 1) status = false;
+                        if (edit1 < 1)
+                        {
+                            _jv.Msg = $"批次库存更新失败!";
+                            return _jv;
+                        }
                     }
 
-                    //3.2 添加入库批次关联领用人
+                    //2.2.2 添加入库批次关联领用人
                     if (goodsReceiveInfos.Count > 0)
                     {
-                        var edit1 = await _sqlSugar.Updateable<Pm_GoodsReceive>()
-                            .SetColumns(x => new Pm_GoodsReceive()
-                            {
-                                GoodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos)
-                            })
-                            .Where(x => x.Id == id)
-                            .ExecuteCommandAsync();
-                        if (edit1 < 1) status = false;
+                        goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);
                     }
                 }
-                else if (auditEnum == GoodsAuditEnum.Pending)
+
+            }
+            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1)
+            {
+                //出库确认中
+                auditEnum = GoodsAuditEnum.OutConfirming;
+
+                if (preChangeStatus == GoodsAuditEnum.OutConfirmed)
                 {
-                    var goodsStorageInfo = currInfo.GoodsStorageInfo;
+                    var goodsStorageInfo1 = receiveInfo.GoodsStorageInfo;
                     if (!string.IsNullOrEmpty(goodsStorageInfo))
                     {
                         var goodsStorageInfos = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(goodsStorageInfo);
-                        if (goodsStorageInfos.Count > 0)
+                        if (goodsStorageInfos.Any())
                         {
                             foreach (var item in goodsStorageInfos)
                             {
                                 var newStorageInfo = await _sqlSugar.Queryable<Pm_GoodsStorage>()
                                     .Where(x => x.IsDel == 0 && x.Id == item.StorageId)
                                     .FirstAsync();
-                                if (newStorageInfo != null)
-                                {
-                                    var newEdit = await _sqlSugar.Updateable(newStorageInfo)
+                                if (newStorageInfo == null) continue;
+
+                                var newEdit = await _sqlSugar.Updateable(newStorageInfo)
                                         .ReSetValue(x => x.ReceiveQuantity = x.ReceiveQuantity - item.Quantity)
                                         .ExecuteCommandAsync();
-                                    if (newEdit < 1) status = false;
+
+                                if (newEdit < 1)
+                                {
+                                    _jv.Msg = $"批次领用库存更新失败!";
+                                    return _jv;
                                 }
                             }
                         }
                     }
                 }
             }
+            else
+            {
+                auditEnum = GoodsAuditEnum.OutPending;
+            }
 
-            if (status)
+            var statusDesc1 =statusDesc.ToString();
+
+            var changeStatus = await _sqlSugar
+                .Updateable<Pm_GoodsReceive>()
+                .SetColumns(x => new Pm_GoodsReceive()
+                {
+                    AuditStatus = auditEnum,
+                    StatusDesc = statusDesc1,
+                    GoodsStorageInfo = goodsStorageInfo,
+                })
+                .Where(x => x.Id == receiveInfo.Id)
+                .ExecuteCommandAsync();
+
+            if (changeStatus > 0)
             {
-                _sqlSugar.CommitTran();
-                _jv.Msg = $"操作成功!";
                 _jv.Code = StatusCodes.Status200OK;
-                return _jv;
             }
 
-            _sqlSugar.RollbackTran();
             return _jv;
         }
 
@@ -1528,9 +2119,9 @@ namespace OASystem.Infrastructure.Repositories.PersonnelModule
                 .Queryable<Pm_GoodsReceive>()
                 .Where(x => x.IsDel == 0 && x.Id == id)
                 .FirstAsync();
-            if (receiveInfo.AuditStatus == GoodsAuditEnum.Approved)
+            if (receiveInfo.AuditStatus >= GoodsAuditEnum.Approved)
             {
-                _jv.Msg = $"该条数据已通过审核,不可删除!";
+                _jv.Msg = $"该条数据已进入审批流程,不可删除!";
                 return _jv;
             }