using BPA.MES.Base.Application.Entitys.Base;
using Furion.EventBus;
using Microsoft.AspNetCore.Cors.Infrastructure;
using System.Security.Cryptography;
using Yitter.IdGenerator;

namespace BPA.MES.Base.Application.Services.WorkInfoService.Services
{
    /// <summary>
    /// 名    称 ：工单服务  
    /// 创 建 人 ：yangxiao  
    /// 创建时间 ：2023/7/20 14:39:41 
    /// 描    述 ：  
    /// </summary>
    [ApiDescriptionSettings("工单服务", Order = 0, Tag = "工单服务", Name = "WorkInfo", KeepName = true, SplitCamelCase = true, KeepVerb = true)]
    public class WorkInfoService : IWorkInfoService, ITransient, IDynamicApiController
    {
        private readonly ISqlSugarClient _dbContext;
        private readonly IMQTTService _MQTTService;
        public WorkInfoService(ISqlSugarClient db, IEventPublisher eventPublisher, IMQTTService MQTTService)
        {
            _dbContext = db;
            _MQTTService = MQTTService;
        }
        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost, OperLog("增加工单")]
        public async Task<bool> Add(WorkInfoAddInput input)
        {
            bool result = false;
            var planEntity =await _dbContext.Queryable<WorkPlanEntity>().Where(x=>x.Id==input.PlanId).FirstAsync();
            Pztj_WorkInfoEntity entity = input.Adapt<Pztj_WorkInfoEntity>();
            entity.FinalId = planEntity.FinalId;
            List<WorkDeviceRecordEntity> workDeviceRecordEntities = new();
            foreach (var item in input.WorkDevices)
            {
                WorkDeviceRecordEntity workDeviceRecordEntity = new()
                {
                    DeviceId = item.DeviceId,
                    WorkId = entity.Id,
                    ProcessId = item.ProcessId,
                    LineId = input.LineId,
                };
                workDeviceRecordEntities.Add(workDeviceRecordEntity);
            }
            Pztj_WorkInfoStatusEntity pztj_WorkInfoStatusEntity = new()
            {
                Status = WorkOrderStatusEnum.Draft,
                WorkId = entity.Id
            };
            try
            {
                _dbContext.Ado.BeginTran();
                await _dbContext.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                if (workDeviceRecordEntities.Count>1)
                {
                    await _dbContext.Insertable(workDeviceRecordEntities).ExecuteCommandAsync();
                }
                await _dbContext.Insertable(pztj_WorkInfoStatusEntity).IgnoreColumns(true).ExecuteCommandAsync();
                _dbContext.Ado.CommitTran();
                result = true;
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Bah("添加失败!");
            }
            return result;
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Del(WorkInfoDelInput input)
        {
            var res = await _dbContext.Deleteable<Pztj_WorkInfoEntity>().Where(x => x.Id == input.Id).ExecuteCommandHasChangeAsync();
            return res;
        }
        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet]
        public async Task<WorkInfoDetailOutput> Detail(string Id)
        {
            var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                 .LeftJoin<Pztj_FinalsInfoEntity>((a, b) => a.FinalId == b.Id)
                 .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                 .LeftJoin<Pztj_WorkInfoStatusEntity>((a, b, c, d) => d.Id == SqlFunc.Subqueryable<Pztj_WorkInfoStatusEntity>().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
                 .LeftJoin<Pztj_DevicesInfoEntity>((a, b, c, d, e) => a.DeviceId==e.Id)
                 .Where((a, b, c, d) => a.Id == Id)
                 .Select((a, b, c, d, e) => new WorkInfoDetailOutput
                 {
                     Id = a.Id.SelectAll(),
                     DeviceCode = e.Code,
                     DeviceName=e.Name,
                     DeviceId = e.Id,
                     FinalName = b.Name,
                     LineName = c.Name,
                     Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status
                 }).FirstAsync();
            if (entity == null)
            {
                throw Oops.Bah("没有找到工单信息!");
            }
            //获取成品信息
            var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == entity.FinalId);
            if (finainfo == null)
            {
                throw Oops.Bah("没有找到成品信息!");
            }
            //获取工艺步骤
            var craftlist = await _dbContext.Queryable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == Id).ToListAsync();
            //获取物料信息
            var materiallist = await _dbContext.Queryable<WorkInfoMaterialsRecordEntity>()
                .LeftJoin<Pztj_MaterialsInfoEntity>((a, b) => a.MaterialId==b.Id)
                 .LeftJoin<DictDataEntity>((a, b, c) => b.Type == c.Id)
                .Where((a, b) => a.WorkId == Id)
                .Select((a, b, c) =>
                new WorkInfoMaterialsRecordOutput
                {
                    Id = a.Id.SelectAll(),
                    MaterialType = c.Id,
                    MaterialTypeName = c.Value,
                    WeightPerLiter = b.WeightPerLiter
                })
                .ToListAsync();
            entity.CraftList = craftlist;
            entity.MaterialList = materiallist;
            if (craftlist.Max(x => x.Status) == RecipeStatus.执行完成 && craftlist.Max(x => x.Status) == craftlist.Min(x => x.Status))
            {
                entity.CraftStatus = RecipeStatus.执行完成;
            }
            else
             if (craftlist.Max(x => x.Status) == RecipeStatus.等待执行 && craftlist.Max(x => x.Status) == craftlist.Min(x => x.Status))
            {
                entity.CraftStatus = RecipeStatus.等待执行;
            }
            else
            {
                entity.CraftStatus = RecipeStatus.正在执行;
            }

            if (materiallist.Max(x => x.MaterialStatus) == EBatchingStatus.配料完成 && materiallist.Max(x => x.MaterialStatus) == materiallist.Min(x => x.MaterialStatus))
            {
                entity.MaterialStatus = EBatchingStatus.配料完成;
            }
            else
             if (materiallist.Max(x => x.MaterialStatus) == EBatchingStatus.等待配料 && materiallist.Max(x => x.MaterialStatus) == materiallist.Min(x => x.MaterialStatus))
            {
                entity.MaterialStatus = EBatchingStatus.等待配料;
            }
            else
            {
                entity.MaterialStatus = EBatchingStatus.正在配料;
            }
            return entity;
        }
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<List<WorkInfoOutput>> List(WorkInfoQueryInput input)
        {
            var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                 .LeftJoin<Pztj_FinalsInfoEntity>((a, b) => a.FinalId == b.Id)
                 .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                 .LeftJoin<Pztj_DevicesInfoEntity>((a, b, c, d) => a.DeviceId==d.Id)
                 .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c, d) => b.Name.Contains(input.Name))
                 .WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c, d) => a.Id.Contains(input.Id))
                 .WhereIF(!string.IsNullOrEmpty(input.BatchId), (a, b, c, d) => a.BatchId == input.BatchId)
                  .WhereIF(input.Status != null, (a, b, c, d) => input.Status.Contains(a.Status))
                  .WhereIF(input.StartTime != null, (a, b, c, d) => input.StartTime <= Convert.ToDateTime(a.CreateTime))
                  .WhereIF(input.EndTime != null, (a, b, c, d) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= Convert.ToDateTime(a.CreateTime))
                  .OrderByDescending((a, b, c, d) => a.CreateTime)
                 .Select((a, b, c, d) => new WorkInfoOutput
                 {
                     Id = a.Id,
                     FinalName = b.Name,
                     LineName = c.Name,
                     DeviceId = a.DeviceId == null ? "" : a.DeviceId,
                     DeviceName =d.Name,
                     Status = a.Status == null ? WorkOrderStatusEnum.Draft : a.Status,
                     BatchId = a.BatchId,
                     Number = a.Number,
                     FinalId = a.FinalId,
                     LineId = a.LineId,
                     DeviceCode = a.DeviceId,
                     CreateTime = a.CreateTime
                 }).ToListAsync();
            return entity;
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SqlSugarPagedList<WorkInfoOutput>> PagedList(WorkInfoQueryPageInput input)
        {
            var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                .LeftJoin<Pztj_FinalsInfoEntity>((a, b) => a.FinalId == b.Id)
                .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c) => b.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c) => a.Id.Contains(input.Id))
                .WhereIF(!string.IsNullOrEmpty(input.BatchId), (a, b, c) => a.BatchId==input.BatchId)
                 .WhereIF(input.Status != null, (a, b, c) => input.Status.Contains(a.Status))
                 .WhereIF(input.StartTime != null, (a, b, c) => input.StartTime <= Convert.ToDateTime(a.CreateTime))
                 .WhereIF(input.EndTime != null, (a, b, c) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= Convert.ToDateTime(a.CreateTime))
                 .OrderByDescending((a, b, c) => a.CreateTime)
                .Select((a, b, c) => new WorkInfoOutput
                {
                    Id = a.Id.SelectAll(),
                    FinalName = b.Name,
                    LineName = c.Name,
                    DeviceId = a.DeviceId ?? "",
                    Status = a.Status == null ? WorkOrderStatusEnum.Draft : a.Status
                })
                .ToPagedListAsync(input.PageIndex, input.PageSize);
            return entity;
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SqlSugarPagedList<WorkInfoOutput>> BatchPagedList(WorkInfoQueryPageInput input)
        {
            var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                .LeftJoin<Pztj_FinalsInfoEntity>((a, b) => a.FinalId == b.Id)
                .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c) => b.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c) => a.Id.Contains(input.Id))
                 .WhereIF(input.Status != null, (a, b, c) => input.Status.Contains(a.Status))
                 .WhereIF(input.StartTime != null, (a, b, c) => input.StartTime <= Convert.ToDateTime(a.CreateTime))
                 .WhereIF(input.EndTime != null, (a, b, c) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= Convert.ToDateTime(a.CreateTime))
                 .OrderByDescending((a, b, c) => a.CreateTime)
                .Select((a, b, c) => new WorkInfoOutput
                {
                    Id = a.Id.SelectAll(),
                    FinalName = b.Name,
                    LineName = c.Name,
                    Status = a.Status == null ? WorkOrderStatusEnum.Draft : a.Status
                })
                .ToPagedListAsync(input.PageIndex, input.PageSize);
            return entity;
        }

        /// <summary>
        /// 工单下发
        /// </summary>
        /// <param name="input">工单id</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Publishs(BatchInput input)
        {
            string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            string userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
            var workentitys = await _dbContext.Queryable<Pztj_WorkInfoEntity>().Where(x => x.BatchId == input.BatchId).ToListAsync();

            foreach (var item in workentitys)
            {
                var res = await UpdateStatus(
                        new WorkInfoStatusUpdateInput
                        {
                            WorkId = item.Id,
                            Status = WorkOrderStatusEnum.Issued,
                            Remark = $"[{userId}]{userName}"
                        });
                var workentity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                    .LeftJoin<Pztj_DevicesInfoEntity>((a, b) => a.DeviceId == b.Id)
                    .Where((a, b) => a.Id == item.Id)
                    .Select((a, b) => new WorkInfoOutput
                    {
                        Id = a.Id.SelectAll(),
                        DeviceCode = b.Code,
                        DeviceName = b.Name
                    })
                    .FirstAsync();
                if (res)
                {
                    WorkInfoMaterialsRecordEntity workInfoMaterialsRecordEntity = new()
                    {
                        MaterialId = item.Id,
                    };
                    //获取成品信息
                    var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == workentity.FinalId);
                    if (finainfo == null)
                    {
                        throw Oops.Bah("没有找到成品信息!");
                    }

                    var materiallist = await _dbContext.Queryable<RecipeMaterialEntity>()
                        .LeftJoin<Pztj_MaterialsInfoEntity>((a, b) => a.MaterialId == b.Id)
                        .LeftJoin<RecipesInfoEntity>((a, b, c) => a.RecipesId == c.Id)
                         //.Where((a, b, c) => a.RecipesId == finainfo.RecipeId)
                         .Select((a, b, c) => new WorkInfoMaterialsRecordEntity
                         {
                             MaterialId = a.MaterialId,
                             MaterialName = b.Name,
                             MaterialStatus = EBatchingStatus.等待配料,
                             WorkId = item.Id,
                             Weight = a.Weight,
                             RecipeId = a.RecipesId,
                             RecipeName = c.Name
                         })
                        .ToListAsync();

                    //获取物料信息

                    var craftsteplist = await _dbContext.Queryable<Pztj_CraftStepsEntity>()
                        .LeftJoin<Pztj_CraftsInfoEntity>((a, b) => a.CraftId == b.Id)
                        .LeftJoin<DeviceProductFunctionEntity>((a, b, c) => a.DeviceProductFunctionId == c.Id)
                        //.Where((a, b) => a.CraftId == finainfo.CraftId)
                        .Select((a, b, c) => new WorkInfoCraftstepRecordEntity
                        {
                            CraftId = a.CraftId,
                            CraftName = b.Name,
                            CraftstepId = a.Id,
                            DeviceProductFunctionId = c.Id,
                            DeviceProductFunctionName = c.Name,
                            CraftstepParms = a.Params,
                            Status = RecipeStatus.等待执行,
                            Step = a.Step,
                            WorkId = item.Id
                        })
                        .ToListAsync();
                    List<WorkInfoMaterialsRecordEntity> newmateriallist = new();
                    List<WorkInfoCraftstepRecordEntity> newcraftslist = new();
                    for (int i = 1; i <= Convert.ToInt32(workentity.Number); i++)
                    {
                        foreach (var materiaItem in materiallist)
                        {
                            WorkInfoMaterialsRecordEntity itementity = new()
                            {
                                PotNum = i.ToString(),
                                MaterialId = materiaItem.MaterialId,
                                MaterialName = materiaItem.MaterialName,
                                MaterialStatus = materiaItem.MaterialStatus,
                                WorkId = materiaItem.WorkId,
                                Weight = materiaItem.Weight,
                                RecipeId = materiaItem.RecipeId,
                                RecipeName = materiaItem.RecipeName,
                            };
                            newmateriallist.Add(itementity);
                        }
                        foreach (var craftstepitem in craftsteplist)
                        {
                            WorkInfoCraftstepRecordEntity itementity = new()
                            {
                                CraftId = craftstepitem.CraftId,
                                CraftName = craftstepitem.CraftName,
                                CraftstepId = craftstepitem.CraftstepId,
                                DeviceProductFunctionId = craftstepitem.DeviceProductFunctionId,
                                DeviceProductFunctionName = craftstepitem.DeviceProductFunctionName,
                                CraftstepParms = craftstepitem.CraftstepParms,
                                Status = craftstepitem.Status,
                                Step = craftstepitem.Step,
                                WorkId = craftstepitem.WorkId,
                                PotNum = i.ToString(),
                            };
                            newcraftslist.Add(itementity);
                        }
                    }
                    try
                    {
                        _dbContext.Ado.BeginTran();
                        await _dbContext.Deleteable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == item.Id).ExecuteCommandAsync();
                        await _dbContext.Deleteable<WorkInfoMaterialsRecordEntity>().Where(x => x.WorkId == item.Id).ExecuteCommandAsync();

                        await _dbContext.Insertable(newcraftslist).ExecuteCommandAsync();
                        await _dbContext.Insertable(newmateriallist).ExecuteCommandAsync();
                        _dbContext.Ado.CommitTran();
                    }
                    catch (Exception ex)
                    {
                        _dbContext.Ado.RollbackTran();
                        throw Oops.Oh("下发失败!");
                    }
                    await _MQTTService.MqttPublish(new MqttPublishDto() { Payload = workentity, Topic = Topics.WorkOrderPush, MessageId = MessageID.WorkOrderIssued });
                }
            }
            await _dbContext.Updateable<WorkBatchEntity>().SetColumns(x => x.Status == WorkOrderStatusEnum.Issued).Where(x => x.Id == input.BatchId).ExecuteCommandAsync();
            return true;
        }

        /// <summary>
        /// 工单下发
        /// </summary>
        /// <param name="input">工单id</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Publish(PublishInput input)
        {
            string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            string userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
            if (!string.IsNullOrEmpty(input.DeviceId))
            {
                await _dbContext.Updateable<Pztj_WorkInfoEntity>().SetColumns(x => x.DeviceId == input.DeviceId).Where(x => x.Id == input.WorkId).ExecuteCommandAsync();
            }
            var res = await UpdateStatus(
                    new WorkInfoStatusUpdateInput
                    {
                        WorkId = input.WorkId,
                        Status = WorkOrderStatusEnum.Issued,
                        Remark = $"[{userId}]{userName}"
                    });
            var workentity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                .LeftJoin<Pztj_DevicesInfoEntity>((a, b) => a.DeviceId==b.Id)
                .Where((a, b) => a.Id == input.WorkId)
                .Select((a, b) => new WorkInfoOutput
                {
                    Id=a.Id.SelectAll(),
                    DeviceCode = b.Code,
                    DeviceName = b.Name
                })
                .FirstAsync();
            if (res)
            {
                WorkInfoMaterialsRecordEntity workInfoMaterialsRecordEntity = new()
                {
                    MaterialId = input.WorkId,
                };
                //获取成品信息
                var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == workentity.FinalId);
                if (finainfo == null)
                {
                    throw Oops.Bah("没有找到成品信息!");
                }

                var materiallist = await _dbContext.Queryable<RecipeMaterialEntity>()
                    .LeftJoin<Pztj_MaterialsInfoEntity>((a, b) => a.MaterialId == b.Id)
                    .LeftJoin<RecipesInfoEntity>((a, b, c) => a.RecipesId==c.Id)
                     //.Where((a, b, c) => a.RecipesId == finainfo.RecipeId)
                     .Select((a, b, c) => new WorkInfoMaterialsRecordEntity
                     {
                         MaterialId = a.MaterialId,
                         MaterialName = b.Name,
                         MaterialStatus = EBatchingStatus.等待配料,
                         WorkId = input.WorkId,
                         Weight = a.Weight,
                         RecipeId = a.RecipesId,
                         RecipeName = c.Name,
                         ErrorWeight = a.ErrorWeight,
                     })
                    .ToListAsync();

                //获取物料信息

                var craftsteplist = await _dbContext.Queryable<Pztj_CraftStepsEntity>()
                    .LeftJoin<Pztj_CraftsInfoEntity>((a, b) => a.CraftId == b.Id)
                    .LeftJoin<DeviceProductFunctionEntity>((a, b, c) => a.DeviceProductFunctionId == c.Id)
                    //.Where((a, b) => a.CraftId == finainfo.CraftId)
                    .Select((a, b, c) => new WorkInfoCraftstepRecordEntity
                    {
                        CraftId = a.CraftId,
                        CraftName = b.Name,
                        CraftstepId = a.Id,
                        DeviceProductFunctionId = c.Id,
                        DeviceProductFunctionName = c.Name,
                        CraftstepParms = a.Params,
                        Status = RecipeStatus.等待执行,
                        Step = a.Step,
                        WorkId = input.WorkId
                    })
                    .ToListAsync();
                List<WorkInfoMaterialsRecordEntity> newmateriallist = new();
                List<WorkInfoCraftstepRecordEntity> newcraftslist = new();
                for (int i = 1; i <= Convert.ToInt32(workentity.Number); i++)
                {
                    foreach (var item in materiallist)
                    {
                        WorkInfoMaterialsRecordEntity itementity = new()
                        {
                            PotNum = i.ToString(),
                            MaterialId = item.MaterialId,
                            MaterialName = item.MaterialName,
                            MaterialStatus = item.MaterialStatus,
                            WorkId = item.WorkId,
                            Weight = item.Weight,
                            RecipeId = item.RecipeId,
                            RecipeName = item.RecipeName,
                            ErrorWeight = item.ErrorWeight
                        };
                        newmateriallist.Add(itementity);
                    }
                    foreach (var item in craftsteplist)
                    {
                        WorkInfoCraftstepRecordEntity itementity = new()
                        {
                            CraftId = item.CraftId,
                            CraftName = item.CraftName,
                            CraftstepId = item.CraftstepId,
                            DeviceProductFunctionId = item.DeviceProductFunctionId,
                            DeviceProductFunctionName = item.DeviceProductFunctionName,
                            CraftstepParms = item.CraftstepParms,
                            Status = item.Status,
                            Step = item.Step,
                            WorkId = item.WorkId,
                            PotNum = i.ToString(),
                        };
                        newcraftslist.Add(itementity);
                    }
                }
                try
                {
                    _dbContext.Ado.BeginTran();
                    await _dbContext.Deleteable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == input.WorkId).ExecuteCommandAsync();
                    await _dbContext.Deleteable<WorkInfoMaterialsRecordEntity>().Where(x => x.WorkId == input.WorkId).ExecuteCommandAsync();

                    await _dbContext.Insertable(newcraftslist).ExecuteCommandAsync();
                    await _dbContext.Insertable(newmateriallist).ExecuteCommandAsync();
                    _dbContext.Ado.CommitTran();
                }
                catch (Exception ex)
                {
                    _dbContext.Ado.RollbackTran();
                    throw Oops.Oh("下发失败!");
                }
                await _MQTTService.MqttPublish(new MqttPublishDto() { Payload = workentity, Topic = Topics.WorkOrderPush, MessageId = MessageID.WorkOrderIssued });
            }
            return true;
        }
        /// <summary>
        /// 下拉
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet]
        public async Task<dynamic> SelectList()
        {
            var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>().Select(x => new
            {
                key = x.Id,
                value = x.Name
            }).ToListAsync();
            return entity;
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Update(WorkInfoUpdateInput input)
        {
            bool result = false;
            Pztj_WorkInfoEntity entity = input.Adapt<Pztj_WorkInfoEntity>();
            List<WorkDeviceRecordEntity> workDeviceRecordEntities = new();
            foreach (var item in input.WorkDevices)
            {
                WorkDeviceRecordEntity workDeviceRecordEntity = new()
                {
                    DeviceId = item.DeviceId,
                    WorkId = entity.Id,
                    ProcessId = item.ProcessId,
                    LineId = input.LineId,
                };
                workDeviceRecordEntities.Add(workDeviceRecordEntity);
            }
            Pztj_WorkInfoStatusEntity pztj_WorkInfoStatusEntity = new()
            {
                Status = WorkOrderStatusEnum.Draft,
                WorkId = entity.Id
            };
            try
            {
                _dbContext.Ado.BeginTran();
                await _dbContext.Updateable(entity).Where(x => x.Id==input.Id).IgnoreColumns(true).ExecuteCommandAsync();
                await _dbContext.Deleteable<WorkDeviceRecordEntity>().Where(x => x.WorkId==input.Id).ExecuteCommandAsync();
                if (workDeviceRecordEntities.Count>1)
                {
                    await _dbContext.Insertable(workDeviceRecordEntities).ExecuteCommandAsync();
                }
                _dbContext.Ado.CommitTran();
                result = true;
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Bah("添加失败!");
            }
            return result;
        }
        /// <summary>
        /// 修改工单状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> UpdateStatus(WorkInfoStatusUpdateInput input)
        {
            var entitys = await _dbContext.Queryable<Pztj_WorkInfoEntity>().Where(x => x.Id == input.WorkId)
              .FirstAsync();
            Pztj_WorkInfoStatusEntity entity = input.Adapt<Pztj_WorkInfoStatusEntity>();
            try
            {
                _dbContext.Ado.BeginTran();
                await _dbContext.Insertable(entity).IgnoreColumns(true).ExecuteCommandIdentityIntoEntityAsync();
                await _dbContext.Updateable<Pztj_WorkInfoEntity>().SetColumns(x => x.Status == input.Status).Where(x => x.Id == input.WorkId).ExecuteCommandAsync();
                _dbContext.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Bah("更新失败");
            }
            var workItems = await _dbContext.Queryable<Pztj_WorkInfoEntity>().LeftJoin<Pztj_WorkInfoStatusEntity>((a, b) => a.Id == b.WorkId).Where(a => a.BatchId == entitys.BatchId)
                .Select((a, b) => new WorkInfoOutput
                {
                    Id = a.Id.SelectAll(),
                    Status = b.Status,
                })
                .ToListAsync();
            if (workItems.Max(x => x.Status) == WorkOrderStatusEnum.Completed && workItems.Min(x => x.Status) == WorkOrderStatusEnum.Completed)
            {
                await _dbContext.Updateable<WorkBatchEntity>().SetColumns(x => x.Status == WorkOrderStatusEnum.Completed).Where(x => x.Id == entitys.BatchId).ExecuteCommandAsync();
            }
            else
            {
                await _dbContext.Updateable<WorkBatchEntity>().SetColumns(x => x.Status == workItems.Max(x => x.Status)).Where(x => x.Id == entitys.BatchId).ExecuteCommandAsync();
            }
            return true;
        }
        /// <summary>
        /// 修改工单物料状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> UpdateWorkMaterialStatus(WorkInfoMaterialsRecordUpdateInput input)
        {
            WorkInfoMaterialsRecordEntity entity = new()
            {
                Id = input.WorkMaterialId,
                MaterialStatus = input.Status,
                UpdateTime = DateTime.Now
            };
            bool res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
            return res;
        }
        /// <summary>
        /// 修改工单步骤状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> UpdateWorkCraftStepsStatus(WorkInfoCraftstepRecordUpdateInput input)
        {


            var entityFrist = await _dbContext.Queryable<WorkInfoCraftstepRecordEntity>().Where(x => x.Id == input.WorkCraftstepId).FirstAsync();
            if (entityFrist==null)
            {
                throw Oops.Bah("未查询到工单信息!");
            }
            if (!string.IsNullOrEmpty(input.WorkId))
            {
                bool res = await _dbContext.Updateable<WorkInfoCraftstepRecordEntity>()
                    .SetColumns(x => x.Status == input.Status)
                    .SetColumns(x => x.UpdateTime == DateTime.Now).IgnoreColumns(true).Where(x => x.WorkId == input.WorkId && x.PotNum == input.PotNum).ExecuteCommandHasChangeAsync();
                return res;
            }
            else
            {
                WorkInfoCraftstepRecordEntity entity = new()
                {
                    Id = input.WorkCraftstepId,
                    Status = input.Status,
                    UpdateTime = DateTime.Now,
                    Step = entityFrist.Step
                };
                bool res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
                return res;
            }
        }

        /// <summary>
        /// 强制结束工单
        /// </summary>
        /// <param name="workId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> ForcedEnd(string workId)
        {
            string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            string userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
            await UpdateStatus(new WorkInfoStatusUpdateInput
            {
                WorkId = workId,
                Status = WorkOrderStatusEnum.Completed,
                Remark = $"{userName}[{userId}]点击了强制结束"
            });
            return true;
        }
        /// <summary>
        /// 工单状态变更记录
        /// </summary>
        /// <param name="workId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<WorkInfoStatusOutput>> StatusList(string workId)
        {
            var entitys = await _dbContext.Queryable<Pztj_WorkInfoStatusEntity>().Where(x => x.WorkId == workId).OrderByDescending(x => x.CreateTime).ToListAsync();
            List<WorkInfoStatusOutput> list = entitys.Adapt<List<WorkInfoStatusOutput>>();

            return list;
        }
        /// <summary>
        /// 获取编辑详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<WorkInfoEditDetailOutput> EditDetail(string Id)
        {
            WorkInfoEditDetailOutput entity = new();
            entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>()
                 .LeftJoin<WorkPlanEntity>((a, b) => a.PlanId == b.Id)
                 .LeftJoin<Pztj_FinalsInfoEntity>((a, b, c) => a.FinalId == c.Id)
                 .Where((a, b, c) => a.Id == Id)
                 .Select((a, b, c) => new WorkInfoEditDetailOutput
                 {
                     PlanId = a.PlanId,
                     FinalName = c.Name,
                     LineId = a.LineId,
                     Quantity = b.Quantity
                 }).FirstAsync();
            var devicelist = await _dbContext.Queryable<WorkDeviceRecordEntity>().Where(x => x.WorkId==Id)
                .Select(x => new WorkDeviceAddInput
                {
                    DeviceId = x.DeviceId,
                    ProcessId = x.ProcessId,
                })
                .ToListAsync();
            entity.WorkDevices = devicelist;
            return entity;
        }
    }
}
