Browse Source

跨工厂派工

feature_crossplant
zhangxin 2 years ago
parent
commit
bca7b663dc
5 changed files with 154 additions and 72 deletions
  1. +1
    -1
      common/ProjectChannel.go
  2. +31
    -21
      meta/base/CrossPlanTask.meta.go
  3. +1
    -0
      services/om/SerialOrder.service.go
  4. +111
    -49
      services/om/implments/SerialOrder.Logic.impl.go
  5. +10
    -1
      task/ApsRelease.go

+ 1
- 1
common/ProjectChannel.go View File

@ -4,4 +4,4 @@ import "LAPP_ACURA_MOM_BACKEND/models/channel"
var ReleaseTaskChannel map[int]*channel.ReleaseTaskChannel
var CrossPlantTaskChannel map[int]*channel.ReleaseTaskChannel

+ 31
- 21
meta/base/CrossPlanTask.meta.go View File

@ -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"})

+ 1
- 0
services/om/SerialOrder.service.go View File

@ -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
}
/******************************************************************************


+ 111
- 49
services/om/implments/SerialOrder.Logic.impl.go View File

@ -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
}
}
}

+ 10
- 1
task/ApsRelease.go View File

@ -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
}
}

Loading…
Cancel
Save