From 3731c9e52c19ebf58a9db938954e2351eb4f72d0 Mon Sep 17 00:00:00 2001 From: "leo.xue@le-it.com.cn" Date: Wed, 12 May 2021 09:47:30 +0800 Subject: [PATCH] LEO commit --- models/OM_WOOperation.go | 13 ++- models/OM_WOOperationYieldLst.go | 150 +++++++++++++++++++++++++++++++ models/WorkOrder.go | 4 - service/Const.go | 15 ++++ service/Operation.Ctrl.go | 144 +++++++++++++++++++++++------ service/Order.Ctrl.go | 19 +++- service/Scheduler.Ctrl.go | 27 +++--- 7 files changed, 321 insertions(+), 51 deletions(-) create mode 100644 models/OM_WOOperationYieldLst.go delete mode 100644 models/WorkOrder.go diff --git a/models/OM_WOOperation.go b/models/OM_WOOperation.go index d4c618e..f240b82 100644 --- a/models/OM_WOOperation.go +++ b/models/OM_WOOperation.go @@ -16,10 +16,9 @@ type OmWooperation struct { Descr string `json:"Descr" xorm:"not null NVARCHAR(200)"` Standardoperationid string `json:"StandardOperationId" xorm:"not null NVARCHAR(80)"` Operationtype string `json:"OperationType" xorm:"not null NVARCHAR(40)"` - Status int `json:"Status" xorm:"not null INT(4)"` - Planresourcegroupid string `json:"PlanResourceGroupId" xorm:"not null NVARCHAR(80)"` - Planresourceid string `json:"PlanResourceId" xorm:"not null NVARCHAR(80)"` - Usedresourceid string `json:"UsedResourceId" xorm:"not null NVARCHAR(80)"` + Workplacegrpnr int `json:"WorkPlaceGrpNr" xorm:"not null INT(4)"` + Workplacenr int `json:"WorkPlaceNr" xorm:"not null INT(4)"` + Usedworkplacenr int `json:"UsedWorkPlaceNr" xorm:"not null INT(4)"` Setupduration float32 `json:"SetupDuration" xorm:"not null FLOAT(8)"` Afterprocessduration float32 `json:"AfterProcessDuration" xorm:"not null FLOAT(8)"` Durationuomid string `json:"DurationUomId" xorm:"not null NVARCHAR(80)"` @@ -51,6 +50,7 @@ type OmWooperation struct { Lastuser string `json:"LastUser" xorm:"not null NVARCHAR(40)"` Createtime time.Time `json:"CreateTime" xorm:"DATETIME(8)"` Artlst []OmWooperationartlst `xorm:"-"` + Yieldlst []OmWooperationyieldlst `xorm:"-"` Skilllst []OmWooperationskilllst `xorm:"-"` Toollst []OmWooperationtoollst `xorm:"-"` Resourcelst []OmWooperationresourcelst `xorm:"-"` @@ -180,6 +180,11 @@ func (t *OmWooperation) SelectOne() (data OmWooperation, err error) { t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr).Asc("ArtId").Find(&data.Artlst); err != nil{ return } + // 获取工序的物料产出数据 + if err = e.Table("OmWooperationyieldlst").Where("PlantNr = ? and WorkOrderId = ? and OperationNr = ? and SplitNr = ?", + t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr).Asc("ArtId").Find(&data.Yieldlst); err != nil{ + return + } // 获取工序的工具数据 if err = e.Table("OmWooperationtoollst").Where("PlantNr = ? and WorkOrderId = ? and OperationNr = ? and SplitNr = ?", t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr).Asc("ToolGrpNr").Find(&data.Toollst); err != nil{ diff --git a/models/OM_WOOperationYieldLst.go b/models/OM_WOOperationYieldLst.go new file mode 100644 index 0000000..48533c5 --- /dev/null +++ b/models/OM_WOOperationYieldLst.go @@ -0,0 +1,150 @@ +// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved. +package models + +import ( + "errors" + "leit.com/aps_engine/db" + "time" + "xorm.io/core" +) + +type OmWooperationyieldlst struct { + Plantnr int `json:"PlantNr" xorm:"not null pk INT(4)"` + Workorderid string `json:"WorkOrderId" xorm:"not null pk NVARCHAR(80)"` + Operationnr int `json:"OperationNr" xorm:"not null pk INT(4)"` + Splitnr int `json:"SplitNr" xorm:"not null pk INT(4)"` + Artid string `json:"ArtId" xorm:"not null pk NVARCHAR(80)"` + Descr string `json:"Descr" xorm:"not null NVARCHAR(200)"` + Basisqty float32 `json:"BasisQty" xorm:"not null FLOAT(8)"` + Planqty float32 `json:"PlanQty" xorm:"not null FLOAT(8)"` + Actqty float32 `json:"ActQty" xorm:"not null FLOAT(8)"` + Qtyuomid string `json:"QtyUomId" xorm:"not null NVARCHAR(80)"` + Ctrlpara1 int `json:"CtrlPara1" xorm:"not null INT(4)"` + Ctrlpara2 int `json:"CtrlPara2" xorm:"not null INT(4)"` + Ctrlstr1 string `json:"CtrlStr1" xorm:"not null NVARCHAR(200)"` + Ctrlstr2 string `json:"CtrlStr2" xorm:"not null NVARCHAR(200)"` + Lastmodify time.Time `json:"LastModify" xorm:"DATETIME(8)"` + Lastuser string `json:"LastUser" xorm:"not null NVARCHAR(40)"` + Createtime time.Time `json:"CreateTime" xorm:"DATETIME(8)"` +} + +/******数据表名******/ +func (t *OmWooperationyieldlst) TableName() string { + return "OmWooperationyieldlst" +} + +/****************************************************************************** + * + * @Function Name : + *----------------------------------------------------------------------------- + * + * @Description : 数据添加 + * + * @Function Parameters: + * + * @Return Value : + * + * @Author : Lou Wenzhi + * + * @Date : 2021/3/6 8:47 + * + ******************************************************************************/ +func (t *OmWooperationyieldlst) Add() error { + e := db.Eloquent.Master() + count := new(OmWooperationyieldlst) + /**主键:****/ + affw, err := e.Table(t.TableName()).ID(core.PK{t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr, t.Artid}).Count(count) + if err != nil { + return err + } + if affw > 0 { + return errors.New("数据已经存在!") + } + _, err = e.Table(t.TableName()).Insert(t) + + if err != nil { + return err + } + return nil +} + +/****************************************************************************** + * + * @Function Name : + *----------------------------------------------------------------------------- + * + * @Description : 数据删除 + * + * @Function Parameters: + * + * @Return Value : + * + * @Author : Lou Wenzhi + * + * @Date : 2021/3/6 8:47 + * + ******************************************************************************/ +func (t *OmWooperationyieldlst) Del() (err error) { + e := db.Eloquent.Master() + /**主键:****/ + _, err = e.ID(core.PK{t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr, t.Artid}).Delete(&OmWooperationyieldlst{}) + if err != nil { + return + } + return nil +} + +/****************************************************************************** + * + * @Function Name : + *----------------------------------------------------------------------------- + * + * @Description : 数据修改 + * + * @Function Parameters: + * + * @Return Value : + * + * @Author : Lou Wenzhi + * + * @Date : 2021/3/6 8:47 + * + ******************************************************************************/ +func (t *OmWooperationyieldlst) Update() error { + e := db.Eloquent.Master() + /**主键:****/ + _, err := e.ID(core.PK{t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr, t.Artid}).Update(t) + if err != nil { + return err + } + return nil +} + +/****************************************************************************** + * + * @Function Name : + *----------------------------------------------------------------------------- + * + * @Description : 数据查找 + * + * @Function Parameters: + * + * @Return Value : + * + * @Author : Lou Wenzhi + * + * @Date : 2021/3/6 8:47 + * + ******************************************************************************/ +func (t *OmWooperationyieldlst) SelectOne() (OmWooperationyieldlst, error) { + e := db.Eloquent.Master() + var data OmWooperationyieldlst + /**主键:****/ + _, err := e.ID(core.PK{t.Plantnr, t.Workorderid, t.Operationnr, t.Splitnr, t.Artid}).Get(&data) + if err != nil { + return data, err + } + return data, nil +} + + diff --git a/models/WorkOrder.go b/models/WorkOrder.go deleted file mode 100644 index 5bc6fda..0000000 --- a/models/WorkOrder.go +++ /dev/null @@ -1,4 +0,0 @@ -package models - -/**生产订单**/ - diff --git a/service/Const.go b/service/Const.go index eb84241..10d9bc0 100644 --- a/service/Const.go +++ b/service/Const.go @@ -14,6 +14,8 @@ const ( RES_STATUS_AVAIL = 1 // 资源状态可用 RES_STATUS_UNAVAIL = 0 // 资源状态不可用 + OP_UNSCHEDULED = 0 // 未调度 + OP_SCHEDULED = 1 // 工序在内存中的调度状态:已调度 // 计划资源负载类型 WORKLOAD_TYPE_MONTHLY = "MONTHLY" @@ -34,8 +36,21 @@ const ( ART_CHANGE_CONSUME = 2 // 物料消耗 ART_CHANGE_PRODUCE = 3 // 物料产出 + // 工序资源需求时段 + OP_DEMAND_SETUP = "SETUP" // 换型时段 + OP_DEMAND_PROD = "PROD" // 计划生产时段 + OP_DEMAND_AFTERPROCESS = "AFTERPROCESS" // 后处理时段 + // 表时间字段更新模式 MODIFY_MODE_CREATE = "CREATE" MODIFY_MODE_UPDATE = "UPDATE" MODIFY_MODE_DELETE = "DELETE" + + // 前后工序的关联关系 + OP_RELATION_ES = "ES" // End-Start 前工序结束,本工序才能开始 + OP_RELATION_SS = "SS" // Start-Start 前工序开始,本工序即可开始 + OP_RELATION_SSEE = "SSEE" // Start-Start End-End 前工序开始本工序开始,前工序结束本工序结束(类似于块的概念) + OP_RELATION_EES = "EES" // End-Each-Start 前工序开始与本工序之间的关系,取决于转运批量 + OP_RELATION_ESE = "ESE" // End-Start-Each 前工序结束与本工序之间的关系,取决于转运批量 + ) diff --git a/service/Operation.Ctrl.go b/service/Operation.Ctrl.go index 6cfde58..88c72c9 100644 --- a/service/Operation.Ctrl.go +++ b/service/Operation.Ctrl.go @@ -1,6 +1,7 @@ package service import ( + "leit.com/aps_engine/models" "strconv" "time" ) @@ -10,74 +11,159 @@ type OperationSrv struct{ OperationNr int // 工序号 SplitNr int // 工序拆分号 OrderId string // 订单号 + SchedStatus int // 在内存中的调度状态:0:未调度;1:已调度 Status int // 工序状态 WorkPlaceGrpNr int // 对应资源组号 - ToolGrpNr int // 对应工具组号 + WorkPlaceNr int // 计划工位号 PlanQty float32 - PlanDuration time.Duration // 计划工时 + + SetupDuration time.Duration // 换型工时 SetupStartTime time.Time // 换型开始 SetupEndTime time.Time // 换型结束 + + PlanDuration time.Duration // 计划工时 PlanStartTime time.Time // 计划生产开始 PlanEndTime time.Time // 计划生产结束 + + PostDuration time.Duration // 后处理工时 PostStartTime time.Time // 计划后处理开始 PostEndTime time.Time // 计划后处理结束 - PlanWorkPlaceNr int // 计划工位号 - PlanToolNr int - PrevOpDict map[string]OperationRelSrv // 前工序 - NextOpDict map[string]OperationRelSrv // 后工序 - AttributeDict map[int]OpAttribute // 工序分配的属性 - ToolDemandDict map[int]OpToolDemand // 工序的工具需求 - ArtChangeDict map[string]OpArticleChange // 工序的物料变化 - SkillDemandDict map[int]OpSkillDemand // 工序的技能需求 - SecResDemandDict map[int]OpSecResourceDemand // 工序的次要资源需求 + + PrevOpDict map[string]OperationRelSrv // 前工序 + NextOpDict map[string]OperationRelSrv // 后工序 + AttributeDict map[int]OpAttributeSrv // 工序分配的属性 + ToolDemandDict map[int]OpToolDemandSrv // 工序的工具需求 + ArtDemandDict map[string]OpArticleDemandSrv // 工序的物料需求 + SkillDemandDict map[int]OpSkillDemandSrv // 工序的技能需求 + SecResDemandDict map[int]OpSecResourceDemandSrv // 工序的次要资源需求 + ArtYieldDict map[string]OpArticleYieldSrv // 工序的物料产出 } // 工序分配的属性,用于匹配计划设备 -type OpAttribute struct { +type OpAttributeSrv struct { AttributeNr int } // 工序的工具需求 -type OpToolDemand struct { - ToolNr int - ReqQty int +type OpToolDemandSrv struct { + ToolGrpNr int + ReqQty float32 Operation *OperationSrv } // 工序的物料需求 -type OpArticleChange struct { +type OpArticleDemandSrv struct { ArtId string - ChangeMode int - ChangeQty float64 - Operation *OperationSrv + ReqQty float32 + Operation *OperationSrv +} +// 工序的物料产出(中间品) +type OpArticleYieldSrv struct { + ArtId string + YieldQty float32 + Operation *OperationSrv } // 工序的技能需求 -type OpSkillDemand struct { +type OpSkillDemandSrv struct { SkillNr int - ReqQty int + ReqQty float32 Operation *OperationSrv + DemandPeriod string // 需求时段:SETUP / PROD / AFTERPROCESS } // 工序的次要资源需求 -type OpSecResourceDemand struct { +type OpSecResourceDemandSrv struct { ResourceNr int - ReqQty int + ReqQty float32 Operation *OperationSrv + DemandPeriod string // 需求时段:SETUP / PROD / AFTERPROCESS } // 获取工序键值:工序号-工序拆分号 -func(ops *OperationSrv)GetKey()(string){ +func(ops *OperationSrv)GetOpKey()(string){ return strconv.Itoa(ops.OperationNr) + "-" + strconv.Itoa(ops.SplitNr) } +// 获取工序键值:工序号-工序拆分号 +func(ops *OperationSrv)GetOrdOpKey()(string){ + return ops.OrderId + "-" + strconv.Itoa(ops.OperationNr) + "-" + strconv.Itoa(ops.SplitNr) +} + // 初始化 func(ops *OperationSrv)Init(){ ops.PrevOpDict = make(map[string]OperationRelSrv) ops.NextOpDict = make(map[string]OperationRelSrv) - ops.AttributeDict = make(map[int]OpAttribute) - ops.ToolDemandDict = make(map[int]OpToolDemand) - ops.SkillDemandDict = make(map[int]OpSkillDemand) - ops.ArtChangeDict = make(map[string]OpArticleChange) - ops.SecResDemandDict= make(map[int]OpSecResourceDemand) + ops.AttributeDict = make(map[int]OpAttributeSrv) + ops.ToolDemandDict = make(map[int]OpToolDemandSrv) + ops.SkillDemandDict = make(map[int]OpSkillDemandSrv) + ops.ArtDemandDict = make(map[string]OpArticleDemandSrv) + ops.SecResDemandDict= make(map[int]OpSecResourceDemandSrv) + ops.ArtYieldDict = make(map[string]OpArticleYieldSrv) +} + +// 创建工序对象 +func(ops *OperationSrv)Create(optab models.OmWooperation){ + var ( + optooltab models.OmWooperationtoollst + oparttab models.OmWooperationartlst + opyieldtab models.OmWooperationyieldlst + oprestab models.OmWooperationresourcelst + opskilltab models.OmWooperationskilllst + optoolsrv OpToolDemandSrv + opskillsrv OpSkillDemandSrv + opartsrv OpArticleDemandSrv + opressrv OpSecResourceDemandSrv + opyieldsrv OpArticleYieldSrv + ) + + ops.OrderId = optab.Workorderid + ops.OperationNr = optab.Operationnr + ops.SplitNr = optab.Splitnr + ops.WorkPlaceGrpNr = optab.Workplacegrpnr + ops.WorkPlaceNr = optab.Workplacenr + ops.PrevOpDict = make(map[string]OperationRelSrv) + ops.NextOpDict = make(map[string]OperationRelSrv) + ops.AttributeDict = make(map[int]OpAttributeSrv) + ops.ToolDemandDict = make(map[int]OpToolDemandSrv) + ops.SkillDemandDict = make(map[int]OpSkillDemandSrv) + ops.ArtDemandDict = make(map[string]OpArticleDemandSrv) + ops.SecResDemandDict= make(map[int]OpSecResourceDemandSrv) + ops.ArtYieldDict = make(map[string]OpArticleYieldSrv) + + // 加载工具需求 + for _, optooltab = range optab.Toollst { + optoolsrv = OpToolDemandSrv{Operation: ops} + optoolsrv.ToolGrpNr = optooltab.Toolgrpnr + optoolsrv.ReqQty = optooltab.Planqty + ops.ToolDemandDict[optoolsrv.ToolGrpNr] = optoolsrv + } + // 加载物料需求 + for _, oparttab = range optab.Artlst { + opartsrv = OpArticleDemandSrv{Operation: ops} + opartsrv.ArtId = oparttab.Artid + opartsrv.ReqQty = oparttab.Planqty + ops.ArtDemandDict[opartsrv.ArtId] = opartsrv + } + // 加载物料产出 + for _, opyieldtab = range optab.Yieldlst { + opyieldsrv = OpArticleYieldSrv{Operation: ops} + opyieldsrv.ArtId = opyieldtab.Artid + opyieldsrv.YieldQty = opyieldtab.Planqty + ops.ArtYieldDict[opartsrv.ArtId] = opyieldsrv + } + // 加载技能需求,需要区分需求时段 + for _, opskilltab = range optab.Skilllst { + opskillsrv = OpSkillDemandSrv{Operation: ops} + opskillsrv.SkillNr = opskilltab.Skillnr + opskillsrv.ReqQty = opskilltab.Planqty + opskillsrv.DemandPeriod = opskilltab.Opdemandperiod + } + // 加载次要资源需求,需要区分需求时段 + for _, oprestab = range optab.Resourcelst { + opressrv = OpSecResourceDemandSrv{Operation: ops} + opressrv.ResourceNr = oprestab.Resourcenr + opressrv.ReqQty = oprestab.Planqty + opressrv.DemandPeriod = oprestab.Opdemandperiod + } } // 获取任务计划开始事件 diff --git a/service/Order.Ctrl.go b/service/Order.Ctrl.go index 4fa3fe7..61403c2 100644 --- a/service/Order.Ctrl.go +++ b/service/Order.Ctrl.go @@ -27,23 +27,34 @@ func(os *OrderSrv)Init(){ // 创建订单对象 func(os *OrderSrv)Create(ordtab models.OmWorkorder){ + var ( + optab models.OmWooperation + opsrv *OperationSrv + ) + os.OrderId = ordtab.Workorderid os.ProjectId = ordtab.Projectid os.EarliestStartDate= ordtab.Planstartdate os.LatestEndDate = ordtab.Planenddate - os.OperationArray = []OperationSrv{} os.OperationDict = make(map[string]*OperationSrv) - os.Ordtab = ordtab + + // 遍历工序 + for _, optab = range ordtab.Operationlst { + + opsrv = &OperationSrv{} + opsrv.Create(optab) + os.OperationDict[opsrv.GetOpKey()] = opsrv + } } // 打印订单工序的计划结果 func(os *OrderSrv)Print(){ fmt.Println("生产订单:",os.OrderId) for _, opa := range os.OperationArray { - if op, ok := os.OperationDict[opa.GetKey()]; ok { - fmt.Println("工序号:",op.OperationNr,"工位:",op.PlanWorkPlaceNr,"工时:",op.PlanDuration.Hours(), + if op, ok := os.OperationDict[opa.GetOpKey()]; ok { + fmt.Println("工序号:",op.OperationNr,"工位:",op.WorkPlaceNr,"工时:",op.PlanDuration.Hours(), " 工序开始:",op.PlanStartTime.Format("2006-01-02 15:04:05"), " 工序结束:",op.PlanEndTime.Format("2006-01-02 15:04:05")) } diff --git a/service/Scheduler.Ctrl.go b/service/Scheduler.Ctrl.go index 3baa5b4..8d9a85c 100644 --- a/service/Scheduler.Ctrl.go +++ b/service/Scheduler.Ctrl.go @@ -13,19 +13,20 @@ type SchedulerSrv struct{ PlantNr int StartDate time.Time EndDate time.Time - WorkPlaceDict map[int]*WorkPlaceSrv // 所有的设备对象 + WorkPlaceDict map[int]*WorkPlaceSrv // 所有的设备对象 WorkPlaceGrpDict map[int]*WorkPlaceGrpSrv - ToolDict map[int]*ToolSrv // 所有的工具对象 + ToolDict map[int]*ToolSrv // 所有的工具对象 ToolGrpDict map[int]*ToolGrpSrv - ArticleDict map[string]*ArticleSrv // 所有的物料对象 + ArticleDict map[string]*ArticleSrv // 所有的物料对象 SecResourceDict map[int]*SecondaryResourceSrv // 所有的次要资源对象 - PersonDict map[int]*PersonSrv // 所有人员对象 - SkillDict map[int]*SkillSrv // 所有技能对象 - OrderDict map[string]*OrderSrv - TmSrv TimeModelSrv // 时间模型 + PersonDict map[int]*PersonSrv // 所有人员对象 + SkillDict map[int]*SkillSrv // 所有技能对象 + OrderDict map[string]*OrderSrv // 所有工单对象 + OperationDict map[string]*OperationSrv // 所有订单工序对象 + TmSrv TimeModelSrv // 时间模型 ProjDict map[string]models.MeProject // 激活的项目字典 - SchedRule ScheduleRuleSrv // 调度规则 - SchedEventQueue *SchedQueue // 调度事件队列 + SchedRule ScheduleRuleSrv // 调度规则 + SchedEventQueue *SchedQueue // 调度事件队列 } // 调度引擎初始化 @@ -42,6 +43,7 @@ func(se *SchedulerSrv)Init(plantnr int, stdate, eddate time.Time){ se.PersonDict = make(map[int]*PersonSrv) se.SkillDict = make(map[int]*SkillSrv) se.OrderDict = make(map[string]*OrderSrv) + se.OperationDict = make(map[string]*OperationSrv) se.TmSrv = TimeModelSrv{PlantNr: plantnr} se.SchedEventQueue = NewSchedQueue() } @@ -318,10 +320,11 @@ func(se *SchedulerSrv)LoadResourceData()(err error){ return } -// 加载订单主数据 +// 加载订单主数据(未完成订单) func(se *SchedulerSrv)LoadWorkOrderData()(err error){ var( ordsrv *OrderSrv + opsrv *OperationSrv ordtab models.OmWorkorder vordtablst []models.VWorkorder i int @@ -337,6 +340,10 @@ func(se *SchedulerSrv)LoadWorkOrderData()(err error){ ordsrv = &OrderSrv{} ordsrv.Create(vordtablst[i].OmWorkorder) se.OrderDict[ordsrv.OrderId] = ordsrv + // 加载订单所有的工序对象 + for _, opsrv = range ordsrv.OperationDict { + se.OperationDict[opsrv.GetOrdOpKey()] = opsrv + } } return