作者 yangfu

feat:设备启动状态统计

... ... @@ -45,6 +45,9 @@ func (crontabService *CrontabService) initTask() {
autoFlushDeviceDailyRunningRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 */1 * * * *", AutoFlushDeviceDailyRunningRecord)
task.AddTask("autoFlushDeviceDailyRunningRecord", autoFlushDeviceDailyRunningRecord)
autoWorkshopPlanCompletionRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 1 1-10/3 * * *", AutoWorkshopPlanCompletionRecord)
task.AddTask("autoWorkshopPlanCompletionRecord", autoWorkshopPlanCompletionRecord)
}
func (crontabService *CrontabService) StartCrontabTask() {
... ...
package crontab
import (
"context"
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
)
// 定时刷新车间计划完成纪录
func AutoWorkshopPlanCompletionRecord(ctx context.Context) error {
defer func() {
if r := recover(); r != nil {
log.Logger.Error(fmt.Sprintf("%v", r))
}
}()
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
}
defer func() {
if err != nil {
log.Logger.Error("【定时刷新设备每日运行记录】 失败:" + err.Error())
}
transactionContext.RollbackTransaction()
}()
log.Logger.Debug("【定时刷新设备每日运行记录】 启动")
end := utils.GetZeroTime(time.Now())
begin := utils.GetZeroTime(end.Add(-time.Second))
approveAttendanceRecordsService, _ := domainService.NewPGWorkshopPlanCompletionRecordService(transactionContext.(*pgTransaction.TransactionContext))
if err = approveAttendanceRecordsService.WorkshopPlanCompletion(begin, end); err != nil {
return err
}
if err = transactionContext.CommitTransaction(); err != nil {
return err
}
return nil
}
... ...
... ... @@ -166,9 +166,78 @@ func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 {
// 23:00 1
// 23:59 2
// [{"min":1,"time":"00:01","status":1}]
func (d *DeviceRunningRecordInfo) HourDeviceStatusDetail() {
for i := 0; i < 24; i++ {
func (d *DeviceRunningRecordInfo) HourDeviceStatusDetail(endTime int) map[string]interface{} {
on := make([][]int, 0)
off := make([][]int, 0)
err := make([][]int, 0)
var begin, end int = 0, 0
var status = 1 // 1.故障:1 0 \ 0 0 2.正常:1 1 3.停机:0 1
addToStatus := func(s []int, status int) {
switch status {
case 1:
err = append(err, s)
break
case 2:
on = append(on, s)
break
case 3:
off = append(off, s)
break
}
}
computeStatus := func(up, com int, index int) int {
var val = 0
if up&index > 0 {
val |= 1
}
if com&index > 0 {
val |= 2
}
if val == 1 || val == 0 {
return 1 //故障
}
if val == 3 {
return 2 //正常
}
return 3 // 停机
}
for i := 0; i < 24; i++ {
var index = 1
var hds *HourDeviceStatus
var ok bool
if hds, ok = d.TimeLineDeviceStatus[fmt.Sprintf("%v", i)]; !ok {
hds = &HourDeviceStatus{Window: DefaultTimeWindow}
}
if i == 0 {
status = computeStatus(hds.Up, hds.Com, index) // 状态初始化
}
if end >= endTime {
break
}
if hds.Up == 0 && hds.Com == 0 {
end += 60 / hds.Window
continue
}
for j := 1; j < 60; j++ {
curStatus := computeStatus(hds.Up, hds.Com, index)
if curStatus == status {
end += 1
//continue
} else {
addToStatus([]int{begin, end}, status)
status = curStatus
begin = end + 1
end = begin
}
index = index << 1
}
}
addToStatus([]int{begin, end}, status)
return map[string]interface{}{
"on": on,
"off": off,
"err": err,
}
}
... ...
package dao
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
"time"
)
type WorkshopPlanCompletionRecordDao struct {
transactionContext *pgTransaction.TransactionContext
}
func (dao *WorkshopPlanCompletionRecordDao) Records(companyId, orgId int, workshopId int, begin, end time.Time, records interface{}) error {
tx := dao.transactionContext.PgTx
sql := fmt.Sprintf(`
with product_record as (
select
(case when product_record_type=1 then cast(product_record_info->>'weigh' as DECIMAL)
ELSE -(cast(product_record_info->>'weigh' as DECIMAL))
END) as weight,
cast(product_record_info->>'productPlanId' as INTEGER) plan_id
--,created_at
from manufacture.product_records
where company_id = ?
and org_id =?
and work_station->>'workshopId'='?'
and product_record_type in (1,2)
and created_at>=?
and created_at<?
), product_record_sum as(
select sum(weight) weight,plan_id from product_record
GROUP BY plan_id
)
select
plan_devoted->>'weight' plan_weight -- 计划重量
, coalesce(b.weight,0) real_weight --批次实际产能
,a.product_plan_id
from manufacture.product_plan a left join product_record_sum b on a.product_plan_id = b.plan_id
where company_id = ?
and org_id =?
and workshop->>'workshopId'='?'
and created_at >=?
and created_at<?
order by created_at desc`)
if _, err := tx.Query(records, sql,
companyId, orgId, workshopId, begin, end,
companyId, orgId, workshopId, begin, end); err != nil {
return err
}
return nil
}
func (dao *WorkshopPlanCompletionRecordDao) FindOne(companyId, orgId int, workshopId int, begin time.Time) (*models.WorkshopPlanCompletionRecord, error) {
tx := dao.transactionContext.PgTx
var record = new(models.WorkshopPlanCompletionRecord)
q := tx.Model(record)
q.Where("company_id=?", companyId)
q.Where("org_id=?", orgId)
q.Where("workshop_id=?", workshopId)
q.Where("created_at=?", begin)
err := q.First()
if err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, domain.ErrorNotFound
} else {
return nil, err
}
}
return record, nil
}
func (dao *WorkshopPlanCompletionRecordDao) Save(record *models.WorkshopPlanCompletionRecord) error {
tx := dao.transactionContext.PgTx
if _, err := tx.Model(record).Insert(); err != nil {
return err
}
return nil
}
func NewWorkshopPlanCompletionRecordDao(transactionContext *pgTransaction.TransactionContext) (*WorkshopPlanCompletionRecordDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &WorkshopPlanCompletionRecordDao{
transactionContext: transactionContext,
}, nil
}
}
... ...
... ... @@ -284,6 +284,7 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s
}
var r *domain.DeviceDailyRunningRecord
item := make(map[string]interface{})
//item["id"] = uuid.New().String()
item["orgName"] = d.Ext.OrgName
if d.WorkStation != nil {
item["workshopName"] = d.WorkStation.WorkshopName
... ... @@ -300,7 +301,9 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s
}
}
if r != nil {
item["status"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus
m := r.UpdatedAt.Hour()*60 + r.UpdatedAt.Minute()
item["status"] = r.DeviceRunningRecordInfo.HourDeviceStatusDetail(m)
item["status_info"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus
}
response = append(response, item)
}
... ...
package domainService
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
)
type PGWorkshopPlanCompletionRecordService struct {
transactionContext *pgTransaction.TransactionContext
}
func NewPGWorkshopPlanCompletionRecordService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopPlanCompletionRecordService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &PGWorkshopPlanCompletionRecordService{
transactionContext: transactionContext,
}, nil
}
}
// 车间完成统计
func (ptr *PGWorkshopPlanCompletionRecordService) WorkshopPlanCompletion(begin time.Time, end time.Time) error {
type record struct {
PlanWeight float64 `json:"plan_weight"`
RealWeight float64 `json:"real_weight"`
ProductPlanId float64 `json:"product_plan_id"`
}
cid := constant.MANUFACTURE_DEFAULT_COMPANYID
oid := constant.MANUFACTURE_DEFAULT_ORGID
workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext)
_, workshops, err := workshopRepository.Find(map[string]interface{}{"companyId": cid, "orgId": oid})
if err != nil {
return err
}
if len(workshops) == 0 {
return nil
}
workshopProductRecordDao, _ := dao.NewWorkshopPlanCompletionRecordDao(ptr.transactionContext)
for i := range workshops {
var result = make([]*record, 0)
if err := workshopProductRecordDao.Records(cid, oid, workshops[i].WorkshopId, begin, end, &result); err != nil {
log.Logger.Error(err.Error())
continue
}
var totalPlan float64 = 0
var totalReal float64 = 0
for _, v := range result {
totalPlan += v.PlanWeight
totalReal += v.RealWeight
}
var completionRate float64
if !(totalPlan == 0 || totalReal == 0) {
completionRate = utils.Round(totalReal*100.0/totalPlan, 0)
}
var record *models.WorkshopPlanCompletionRecord
if record, err = workshopProductRecordDao.FindOne(cid, oid, workshops[i].WorkshopId, begin); err == domain.ErrorNotFound && record == nil {
record = &models.WorkshopPlanCompletionRecord{
CompanyId: cid,
OrgId: oid,
WorkshopId: workshops[i].WorkshopId,
WorkshopName: workshops[i].WorkshopName,
CreatedAt: begin,
Plan: totalPlan,
Real: totalReal,
Rate: completionRate,
}
if err := workshopProductRecordDao.Save(record); err != nil {
return err
}
}
}
return nil
}
... ...
... ... @@ -46,6 +46,7 @@ func init() {
(*models.ProductPlanDispatchRecord)(nil),
(*models.DeviceDailyRunningRecord)(nil),
(*models.DeviceRunningRecord)(nil),
(*models.WorkshopPlanCompletionRecord)(nil),
} {
err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
Temp: false,
... ...
package models
import (
"time"
)
// 车间计划完成记录
type WorkshopPlanCompletionRecord struct {
tableName string `comment:"车间" pg:"manufacture.workshop_plan_completion_record"`
WorkshopPlanCompletionRecordId int `comment:"车间计划完成记录ID" pg:"pk:workshop_plan_completion_record_id"`
// 企业id
CompanyId int `comment:"企业id"`
// 组织ID
OrgId int `comment:"组织ID"`
// 生产计划ID
//ProductPlanId int `comment:"生产计划ID" pg:"pk:product_plan_id"`
// 工作位置
//WorkStation *domain.WorkStation `comment:"工作位置"`
// 车间ID
WorkshopId int `comment:"车间"`
// 车间名称
WorkshopName string `comment:"车间名称"`
// 创建时间
CreatedAt time.Time `comment:"创建时间"`
// 计划生成
Plan float64 `comment:"计划生成" pg:",use_zero"`
// 计划生成
Real float64 `comment:"实际生产" pg:",use_zero"`
// 完成率
Rate float64 `comment:"完成率" pg:",use_zero"`
}
... ...