diff --git a/common/ProjectChannel.go b/common/ProjectChannel.go index 0d7d21e..bbae8c9 100644 --- a/common/ProjectChannel.go +++ b/common/ProjectChannel.go @@ -4,4 +4,4 @@ import "LAPP_ACURA_MOM_BACKEND/models/channel" var ReleaseTaskChannel map[int]*channel.ReleaseTaskChannel - +var CrossPlantTaskChannel map[int]*channel.ReleaseTaskChannel \ No newline at end of file diff --git a/meta/base/CrossPlanTask.meta.go b/meta/base/CrossPlanTask.meta.go index 215b1d7..22ddd33 100644 --- a/meta/base/CrossPlanTask.meta.go +++ b/meta/base/CrossPlanTask.meta.go @@ -13,7 +13,7 @@ import ( * * @Author : 代码生成器创建 * - * @Date : 2022-05-10 22:01:07 + * @Date : 2022-05-16 14:55:27 * ******************************************************************************/ var CrossPlanTask_TaskNr = grmi.NewField("TaskNr", "[CrossPlanTask].TaskNr", "tasknr", grmi.TypeInt) @@ -31,6 +31,11 @@ var CrossPlanTask_SourceOrderId = grmi.NewField("SourceOrderId", "[CrossPlanTask var CrossPlanTask_PlanStartTime = grmi.NewField("PlanStartTime", "[CrossPlanTask].PlanStartTime", "planstarttime", grmi.TypeDateTime) var CrossPlanTask_PlanEndTime = grmi.NewField("PlanEndTime", "[CrossPlanTask].PlanEndTime", "planendtime", grmi.TypeDateTime) var CrossPlanTask_Priority = grmi.NewField("Priority", "[CrossPlanTask].Priority", "priority", grmi.TypeInt) +var CrossPlanTask_LastPo = grmi.NewField("LastPo", "[CrossPlanTask].LastPo", "lastpo", grmi.TypeString) +var CrossPlanTask_ReleaseQty = grmi.NewField("ReleaseQty", "[CrossPlanTask].ReleaseQty", "releaseqty", grmi.TypeString) +var CrossPlanTask_StartTime = grmi.NewField("StartTime", "[CrossPlanTask].StartTime", "starttime", grmi.TypeDateTime) +var CrossPlanTask_AccomplishTime = grmi.NewField("AccomplishTime", "[CrossPlanTask].AccomplishTime", "accomplishtime", grmi.TypeDateTime) +var CrossPlanTask_ErrorMsg = grmi.NewField("ErrorMsg", "[CrossPlanTask].ErrorMsg", "errormsg", grmi.TypeString) var CrossPlanTask_LastModify = grmi.NewField("LastModify", "[CrossPlanTask].LastModify", "lastmodify", grmi.TypeDateTime) var CrossPlanTask_LastUser = grmi.NewField("LastUser", "[CrossPlanTask].LastUser", "lastuser", grmi.TypeString) var CrossPlanTask_CreateTime = grmi.NewField("CreateTime", "[CrossPlanTask].CreateTime", "createtime", grmi.TypeDateTime) @@ -41,31 +46,36 @@ var CrossPlanTask_CreateTime = grmi.NewField("CreateTime", "[CrossPlanTask].Crea * * @Author : 代码生成器创建 * - * @Date : 2022-05-10 22:01:07 + * @Date : 2022-05-16 14:55:27 * ******************************************************************************/ var CrossPlanTask = grmi.NewEntity( "CrossPlanTask", func() interface{} { return &model.CrossPlanTask{} }, map[string]grmi.Field{ - CrossPlanTask_TaskNr.Name: CrossPlanTask_TaskNr, - CrossPlanTask_FromPlantNr.Name: CrossPlanTask_FromPlantNr, - CrossPlanTask_ToPlantNr.Name: CrossPlanTask_ToPlantNr, - CrossPlanTask_ProjectId.Name: CrossPlanTask_ProjectId, - CrossPlanTask_ArtId.Name: CrossPlanTask_ArtId, - CrossPlanTask_PlanQty.Name: CrossPlanTask_PlanQty, - CrossPlanTask_ActQty.Name: CrossPlanTask_ActQty, - CrossPlanTask_Status.Name: CrossPlanTask_Status, - CrossPlanTask_OrderType.Name: CrossPlanTask_OrderType, - CrossPlanTask_PlanType.Name: CrossPlanTask_PlanType, - CrossPlanTask_SchedType.Name: CrossPlanTask_SchedType, - CrossPlanTask_SourceOrderId.Name: CrossPlanTask_SourceOrderId, - CrossPlanTask_PlanStartTime.Name: CrossPlanTask_PlanStartTime, - CrossPlanTask_PlanEndTime.Name: CrossPlanTask_PlanEndTime, - CrossPlanTask_Priority.Name: CrossPlanTask_Priority, - CrossPlanTask_LastModify.Name: CrossPlanTask_LastModify, - CrossPlanTask_LastUser.Name: CrossPlanTask_LastUser, - CrossPlanTask_CreateTime.Name: CrossPlanTask_CreateTime, + CrossPlanTask_TaskNr.Name: CrossPlanTask_TaskNr, + CrossPlanTask_FromPlantNr.Name: CrossPlanTask_FromPlantNr, + CrossPlanTask_ToPlantNr.Name: CrossPlanTask_ToPlantNr, + CrossPlanTask_ProjectId.Name: CrossPlanTask_ProjectId, + CrossPlanTask_ArtId.Name: CrossPlanTask_ArtId, + CrossPlanTask_PlanQty.Name: CrossPlanTask_PlanQty, + CrossPlanTask_ActQty.Name: CrossPlanTask_ActQty, + CrossPlanTask_Status.Name: CrossPlanTask_Status, + CrossPlanTask_OrderType.Name: CrossPlanTask_OrderType, + CrossPlanTask_PlanType.Name: CrossPlanTask_PlanType, + CrossPlanTask_SchedType.Name: CrossPlanTask_SchedType, + CrossPlanTask_SourceOrderId.Name: CrossPlanTask_SourceOrderId, + CrossPlanTask_PlanStartTime.Name: CrossPlanTask_PlanStartTime, + CrossPlanTask_PlanEndTime.Name: CrossPlanTask_PlanEndTime, + CrossPlanTask_Priority.Name: CrossPlanTask_Priority, + CrossPlanTask_LastPo.Name: CrossPlanTask_LastPo, + CrossPlanTask_ReleaseQty.Name: CrossPlanTask_ReleaseQty, + CrossPlanTask_StartTime.Name: CrossPlanTask_StartTime, + CrossPlanTask_AccomplishTime.Name: CrossPlanTask_AccomplishTime, + CrossPlanTask_ErrorMsg.Name: CrossPlanTask_ErrorMsg, + CrossPlanTask_LastModify.Name: CrossPlanTask_LastModify, + CrossPlanTask_LastUser.Name: CrossPlanTask_LastUser, + CrossPlanTask_CreateTime.Name: CrossPlanTask_CreateTime, }, []string{}, - []string{"FromPlantNr", "ToPlantNr", "ProjectId", "ArtId", "PlanQty", "ActQty", "Status", "OrderType", "PlanType", "SchedType", "SourceOrderId", "PlanStartTime", "PlanEndTime", "Priority", "LastUser"}) + []string{"FromPlantNr", "ToPlantNr", "ProjectId", "ArtId", "PlanQty", "ActQty", "Status", "OrderType", "PlanType", "SchedType", "SourceOrderId", "PlanStartTime", "PlanEndTime", "Priority", "LastPo", "ReleaseQty", "StartTime", "AccomplishTime", "ErrorMsg", "LastUser"}) diff --git a/services/om/SerialOrder.service.go b/services/om/SerialOrder.service.go index e5c77c3..f8016e0 100644 --- a/services/om/SerialOrder.service.go +++ b/services/om/SerialOrder.service.go @@ -455,6 +455,7 @@ type SerialOrderService interface { GetProductTraceDataReport(user *global.User, serialOrderId string) (interface{}, error) GenerateProductCraft(user *global.User, session *xorm.Session, serialOrder *model.SerialOrder) error ReplaceData(serialOrder *model.SerialOrder, serialNumber string, isPre bool) + SchedCrossPlantTask() error } /****************************************************************************** diff --git a/services/om/implments/SerialOrder.Logic.impl.go b/services/om/implments/SerialOrder.Logic.impl.go index 2d43049..7101348 100644 --- a/services/om/implments/SerialOrder.Logic.impl.go +++ b/services/om/implments/SerialOrder.Logic.impl.go @@ -1,6 +1,7 @@ package implments import ( + "LAPP_ACURA_MOM_BACKEND/common" baseDal "LAPP_ACURA_MOM_BACKEND/dao/base" meDal "LAPP_ACURA_MOM_BACKEND/dao/me" dal "LAPP_ACURA_MOM_BACKEND/dao/om" @@ -12,6 +13,7 @@ import ( meMeta "LAPP_ACURA_MOM_BACKEND/meta/me" meta "LAPP_ACURA_MOM_BACKEND/meta/om" baseModel "LAPP_ACURA_MOM_BACKEND/models/base" + channelModel "LAPP_ACURA_MOM_BACKEND/models/channel" model "LAPP_ACURA_MOM_BACKEND/models/om" "LAPP_ACURA_MOM_BACKEND/utils" "github.com/go-xorm/xorm" @@ -515,18 +517,14 @@ func (impl *SerialOrderServiceImplement) SingleProductTask(user *global.User, se } -// ExecuteCrossPlantTask 执行跨工厂任务 -func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.CrossPlanTask) { +// ExecuteSingleCrossPlantTask 执行跨工厂任务 +func (impl *SerialOrderServiceImplement) ExecuteSingleCrossPlantTask(user *global.User, task baseModel.CrossPlanTask) error { engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() - user := &global.User{ - PlantNr: task.ToPlantNr, - UserId: "MultiPlantTask", - } releaseId, err := uuid.NewV4() if err != nil { - return + return nil } log, _ := logger.NewLogger("跨工厂生成计划,id:"+releaseId.String(), "CrossPlant") taskDao := baseDal.NewCrossPlanTaskDAO(session, user.UserId) @@ -535,40 +533,40 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err != nil { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "查询任务项目失败,错误:" + err.Error() - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } if project == nil { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "任务项目不存在, 项目ID:" + task.ProjectId - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } // 获取生产的物料 productIdLi := strings.Split(task.ArtId, ";") if len(productIdLi) == 0 { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "任务未包含物料数据" - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } if task.PlanEndTime.Restore().Before(task.PlanStartTime.Restore()) { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "任务计划结束时间早于开始时间" - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } // 获取每个总成当前派工数量 releaseQtyStrLi := strings.Split(task.ReleaseQty, ";") @@ -580,11 +578,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr } else if len(releaseQtyStrLi) != len(productIdLi) { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "派工数量格式错误" - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } // 获取当前一共派工的数量 var currentQty int @@ -593,11 +591,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err != nil { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "派工数量格式错误" - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } releaseQtyLi = append(releaseQtyLi, qty) currentQty += qty @@ -610,11 +608,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err != nil || schedQty == 0 { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "不支持的调度模式" - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } // 记录生成计划中间的数量 type ProductQty struct { @@ -635,11 +633,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err != nil { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "生成工单工艺失败, 错误:" + err.Error() - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } productCraftMap[productId] = serialOrderCraft } @@ -656,11 +654,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err = session.Begin(); err != nil { task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "开启事务失败, 错误:" + err.Error() - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } orderCraft := productCraftMap[productQtyCache.ProductId] planStartTime := task.PlanStartTime.Restore().Add(time.Duration(currentQty*perDuration) * time.Second) @@ -669,11 +667,11 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr _ = session.Rollback() task.Status = baseModel.CROSS_TASK_STATUS_ERROR task.ErrorMsg = "保存工单工艺失败, 错误:" + err.Error() - err = taskDao.UpdateOne(&task) - if err != nil { - log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + innerErr := taskDao.UpdateOne(&task) + if innerErr != nil { + log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) } - return + return grmi.NewBusinessError(task.ErrorMsg) } releaseQtyLi[index] += schedQty var totalReleaseQty string @@ -702,12 +700,12 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr if err != nil { _ = session.Rollback() log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) - return + return err } _ = session.Commit() } } - return + return nil } // SaveBatchOrderData 保存总成的工艺数据 @@ -885,4 +883,68 @@ func (impl *SerialOrderServiceImplement) SaveBatchOrderData(user *global.User, s return nil } +// SchedCrossPlantTask 调度跨工厂任务 +func (impl *SerialOrderServiceImplement) SchedCrossPlantTask() error { + engine := db.Eloquent.Master() + session := engine.NewSession() + defer session.Close() + userId := "MultiPlantTask" + plantDao := baseDal.NewPlantDAO(session, userId) + plantLi, err := plantDao.Select(nil, nil) + if err != nil { + return err + } + for _, plant := range plantLi { + user := &global.User{ + PlantNr: plant.PlantNr, + UserId: userId, + } + taskDao := baseDal.NewCrossPlanTaskDAO(session, user.UserId) + taskLi, err := taskDao.Select([]grmi.Predicate{ + baseMeta.CrossPlanTask_ToPlantNr.NewPredicate(grmi.Equal, plant.PlantNr), + baseMeta.CrossPlanTask_Status.NewPredicate(grmi.LessThen, baseModel.CROSS_TASK_STATUS_ACCOMPLISHED), + }, []grmi.Field{baseMeta.CrossPlanTask_Priority, baseMeta.CrossPlanTask_TaskNr}) + channel, exist := common.ReleaseTaskChannel[user.PlantNr] + if !exist { + channel = channelModel.NewReleaseChannel() + common.ReleaseTaskChannel[user.PlantNr] = channel + } + for _, task := range taskLi { + err = channel.SendData(task) + if err != nil { + return err + } + } + go func(user *global.User) { + impl.ExecuteCrossPlantTask(user) + }(user) + } + return nil +} + +// ExecuteCrossPlantTask 执行跨工厂派工 +func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(user *global.User) { + log, _ := logger.NewLogger("跨工厂任务", "MultiPlantTask") + plantNr := user.PlantNr + channel, exist := common.ReleaseTaskChannel[plantNr] + if !exist { + return + } + for { + taskInterface, ok, err := channel.Read() + if err != nil { + return + } + if !ok { + continue + } + task := taskInterface.(baseModel.CrossPlanTask) + err = impl.ExecuteSingleCrossPlantTask(user, task) + if err != nil { + log.Error("派工异常, 错误:" + err.Error()) + channel.Close() + return + } + } +} \ No newline at end of file diff --git a/task/ApsRelease.go b/task/ApsRelease.go index 56c5b2e..733a757 100644 --- a/task/ApsRelease.go +++ b/task/ApsRelease.go @@ -3,12 +3,21 @@ package task import ( "LAPP_ACURA_MOM_BACKEND/common" "LAPP_ACURA_MOM_BACKEND/models/channel" + "LAPP_ACURA_MOM_BACKEND/services/om" "LAPP_ACURA_MOM_BACKEND/services/pln" ) func StartApsRelease() error { + // 异步派工 common.ReleaseTaskChannel = make(map[int]*channel.ReleaseTaskChannel) custSvr := pln.NewCustOrderService() err := custSvr.ReleaseTask() + if err != nil { + return err + } + common.CrossPlantTaskChannel = make(map[int]*channel.ReleaseTaskChannel) + soSrv := om.NewSerialOrderService() + err = soSrv.SchedCrossPlantTask() return err -} + +} \ No newline at end of file