作者 yangfu

feat:增加设备生产效率统计

@@ -73,7 +73,7 @@ func AutoFlushDeviceDailyRunningRecordOEE(ctx context.Context) error { @@ -73,7 +73,7 @@ func AutoFlushDeviceDailyRunningRecordOEE(ctx context.Context) error {
73 device, err := deviceRepository.FindOne(map[string]interface{}{"deviceId": v.DeviceId}) 73 device, err := deviceRepository.FindOne(map[string]interface{}{"deviceId": v.DeviceId})
74 if device != nil && err == nil { 74 if device != nil && err == nil {
75 if device.Ext.DeviceExt != nil { 75 if device.Ext.DeviceExt != nil {
76 - pu = utils.Round(float64((v.DeviceRunningRecordInfo.Count*100.0)/(total/device.Ext.DeviceExt.UnitProductionSecTime)), 1) 76 + pu = utils.Round((float64(v.DeviceRunningRecordInfo.Count)*100.0)/(float64(total)/device.Ext.DeviceExt.UnitProductionSecTime), 1)
77 } 77 }
78 } 78 }
79 // 工段对应二级品数据 79 // 工段对应二级品数据
@@ -35,7 +35,7 @@ type CreateDeviceCommand struct { @@ -35,7 +35,7 @@ type CreateDeviceCommand struct {
35 RiskLevel int `cname:"风险等级 1:高 2:中 3:低" json:"riskLevel" valid:"Required"` 35 RiskLevel int `cname:"风险等级 1:高 2:中 3:低" json:"riskLevel" valid:"Required"`
36 36
37 // 标准工时 生产单个产品的时间(单位:秒) 37 // 标准工时 生产单个产品的时间(单位:秒)
38 - UnitProductionSecTime int `cname:"标准工时" json:"unitProductionSecTime"` 38 + UnitProductionSecTime float64 `cname:"标准工时" json:"unitProductionSecTime"`
39 } 39 }
40 40
41 func (createDeviceCommand *CreateDeviceCommand) Valid(validation *validation.Validation) { 41 func (createDeviceCommand *CreateDeviceCommand) Valid(validation *validation.Validation) {
@@ -2,6 +2,7 @@ package domain @@ -2,6 +2,7 @@ package domain
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "strconv"
5 "time" 6 "time"
6 ) 7 )
7 8
@@ -111,7 +112,7 @@ func (device *Device) Update(data map[string]interface{}) error { @@ -111,7 +112,7 @@ func (device *Device) Update(data map[string]interface{}) error {
111 device.Ext.OrgName = orgName.(string) 112 device.Ext.OrgName = orgName.(string)
112 } 113 }
113 if unitProductionSecTime, ok := data["unitProductionSecTime"]; ok { 114 if unitProductionSecTime, ok := data["unitProductionSecTime"]; ok {
114 - device.Ext.DeviceExt.UnitProductionSecTime = unitProductionSecTime.(int) 115 + device.Ext.DeviceExt.UnitProductionSecTime, _ = strconv.ParseFloat(fmt.Sprintf("%v", unitProductionSecTime), 64)
115 } 116 }
116 device.UpdatedAt = time.Now() 117 device.UpdatedAt = time.Now()
117 return nil 118 return nil
@@ -138,7 +138,7 @@ func (d *DeviceRunningRecordInfo) AddDeviceRunningData(t time.Time, data *Device @@ -138,7 +138,7 @@ func (d *DeviceRunningRecordInfo) AddDeviceRunningData(t time.Time, data *Device
138 d.AddTimeLineDeviceStatus(t, data) 138 d.AddTimeLineDeviceStatus(t, data)
139 139
140 //d.OEE (time.Now().Sub(utils.GetZeroTime(time.Now())).Minutes()) 140 //d.OEE (time.Now().Sub(utils.GetZeroTime(time.Now())).Minutes())
141 - d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 2) 141 + //d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 2)
142 //d.PerformanceUtilization 142 //d.PerformanceUtilization
143 //d.QualificationUtilization 143 //d.QualificationUtilization
144 } 144 }
@@ -173,6 +173,7 @@ func (d *DeviceRunningRecordInfo) ResetUpTime() float64 { @@ -173,6 +173,7 @@ func (d *DeviceRunningRecordInfo) ResetUpTime() float64 {
173 173
174 // 重置设备运行OEE 174 // 重置设备运行OEE
175 func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 { 175 func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 {
  176 + d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 1)
176 d.PerformanceUtilization = pu 177 d.PerformanceUtilization = pu
177 d.QualificationUtilization = qu 178 d.QualificationUtilization = qu
178 d.OEE = utils.Round((d.TimeUtilization*d.PerformanceUtilization*d.QualificationUtilization)/10000, 1) 179 d.OEE = utils.Round((d.TimeUtilization*d.PerformanceUtilization*d.QualificationUtilization)/10000, 1)
@@ -3,7 +3,7 @@ package domain @@ -3,7 +3,7 @@ package domain
3 // DeviceExt 设备扩展 3 // DeviceExt 设备扩展
4 type DeviceExt struct { 4 type DeviceExt struct {
5 // 生产单个产品的时间(单位:秒) 5 // 生产单个产品的时间(单位:秒)
6 - UnitProductionSecTime int `json:"unitProductionSecTime"` 6 + UnitProductionSecTime float64 `json:"unitProductionSecTime"`
7 // 是否是车间设备,如果这个设备有上报过数据,标记 1 默认0 7 // 是否是车间设备,如果这个设备有上报过数据,标记 1 默认0
8 IsProductDevice int `json:"isProductDevice"` 8 IsProductDevice int `json:"isProductDevice"`
9 } 9 }
@@ -59,6 +59,7 @@ from ts_product_list @@ -59,6 +59,7 @@ from ts_product_list
59 return nil 59 return nil
60 } 60 }
61 61
  62 +// 车间性能
62 func (dao *DeviceDailyRunningRecordDao) WorkshopProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error { 63 func (dao *DeviceDailyRunningRecordDao) WorkshopProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
63 64
64 tx := dao.transactionContext.PgTx 65 tx := dao.transactionContext.PgTx
@@ -84,6 +85,38 @@ select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(q @@ -84,6 +85,38 @@ select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(q
84 return nil 85 return nil
85 } 86 }
86 87
  88 +// 设备性能
  89 +func (dao *DeviceDailyRunningRecordDao) DeviceProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
  90 +
  91 + tx := dao.transactionContext.PgTx
  92 + sql := fmt.Sprintf(`
  93 +with device_running as(
  94 +select
  95 +cast(device_running_record_info->>'oee' as DECIMAL) oee,
  96 +cast(device_running_record_info->>'tu' as DECIMAL) tu,
  97 +cast(device_running_record_info->>'pu' as DECIMAL) pu,
  98 +cast(device_running_record_info->>'qu' as DECIMAL) qu,
  99 +cast(device_running_record_info->>'upTime' as DECIMAL) upTime,
  100 +device_id,
  101 +device_code
  102 +from manufacture.device_daily_running_record
  103 +where
  104 +company_id = ?
  105 +and org_id = ?
  106 +and work_station->>'workshopId'='?'
  107 +and created_at>=?
  108 +) ,device_running_oee as(
  109 +select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(qu),1) qu,round(sum(upTime)/60,0) up_time,count(0) t,device_id,max(device_code) device_code from device_running
  110 +GROUP BY device_id
  111 +)
  112 +select * from device_running_oee
  113 + `)
  114 + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil {
  115 + return err
  116 + }
  117 + return nil
  118 +}
  119 +
87 // 时段产能 120 // 时段产能
88 func (dao *DeviceDailyRunningRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error { 121 func (dao *DeviceDailyRunningRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error {
89 122
@@ -109,3 +109,28 @@ func (dao *WorkshopProductRecordDao) SearchWorkshopProductRecord(queryOptions ma @@ -109,3 +109,28 @@ func (dao *WorkshopProductRecordDao) SearchWorkshopProductRecord(queryOptions ma
109 return int64(count), employeeProductRecords, nil 109 return int64(count), employeeProductRecords, nil
110 } 110 }
111 } 111 }
  112 +
  113 +// 设备性能
  114 +func (dao *WorkshopProductRecordDao) WorkStationProductionStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
  115 +
  116 + tx := dao.transactionContext.PgTx
  117 + sql := fmt.Sprintf(`
  118 +with work_station_product as(
  119 + select work_station->>'workStationId' work_station_id,
  120 + COALESCE(cast(product_record_info ->>'inputWeight' as DECIMAL),0) input_weight,
  121 + COALESCE(cast(product_record_info ->>'secondLevelWeight' as DECIMAL),0) second_level_weight,
  122 + product_date
  123 + from manufacture.workshop_product_record
  124 + where company_id = ?
  125 + and org_id = ?
  126 + and work_station->>'workshopId'='?'
  127 + and created_at>=?
  128 +)
  129 +select work_station_id,sum(input_weight) input_weight,sum(second_level_weight) second_level_weight from work_station_product
  130 +group by work_station_id
  131 + `)
  132 + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil {
  133 + return err
  134 + }
  135 + return nil
  136 +}
@@ -21,6 +21,8 @@ const ( @@ -21,6 +21,8 @@ const (
21 ProportionOfSecondLevelStatistics = "ProportionOfSecondLevelStatistics" 21 ProportionOfSecondLevelStatistics = "ProportionOfSecondLevelStatistics"
22 // 车间生产效率 22 // 车间生产效率
23 WorkshopProductionEfficiencyStatistics = "WorkshopProductionEfficiencyStatistics" 23 WorkshopProductionEfficiencyStatistics = "WorkshopProductionEfficiencyStatistics"
  24 + // 设备生产效率
  25 + DeviceProductionEfficiencyStatistics = "DeviceProductionEfficiencyStatistics"
24 // 设备运行统计 26 // 设备运行统计
25 DeviceRunningStatistics = "DeviceRunningStatistics" 27 DeviceRunningStatistics = "DeviceRunningStatistics"
26 // 设备运行信息 28 // 设备运行信息
@@ -51,6 +53,9 @@ func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryO @@ -51,6 +53,9 @@ func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryO
51 case WorkshopProductionEfficiencyStatistics: 53 case WorkshopProductionEfficiencyStatistics:
52 result, err = ptr.WorkshopProductionEfficiencyStatistics(queryOptions) 54 result, err = ptr.WorkshopProductionEfficiencyStatistics(queryOptions)
53 break 55 break
  56 + case DeviceProductionEfficiencyStatistics:
  57 + result, err = ptr.DeviceProductionEfficiencyStatistics(queryOptions)
  58 + break
54 case DeviceRunningStatistics: 59 case DeviceRunningStatistics:
55 result, err = ptr.DeviceRunningStatistics(queryOptions) 60 result, err = ptr.DeviceRunningStatistics(queryOptions)
56 break 61 break
@@ -415,6 +420,105 @@ type DeviceInfo struct { @@ -415,6 +420,105 @@ type DeviceInfo struct {
415 TUptime int `json:"t_uptime"` 420 TUptime int `json:"t_uptime"`
416 } 421 }
417 422
  423 +// 设备生产效率统计
  424 +func (ptr *PGCommonStatisticsService) DeviceProductionEfficiencyStatistics(queryOptions map[string]interface{}) (interface{}, error) {
  425 + var request = &HourProductiveStatisticsRequest{}
  426 + if err := utils.LoadQueryObject(queryOptions, request); err != nil {
  427 + return nil, err
  428 + }
  429 + if request.WorkshopId == 0 {
  430 + request.WorkshopId = constant.MANUFACTURE_DEFAULT_WORKSHOPID
  431 + }
  432 +
  433 + deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext)
  434 + deviceDailyRunningRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext)
  435 + /*
  436 + 1.生产设备
  437 + 2.设备本月运行数据
  438 + */
  439 + _, devices, err := deviceRepository.Find(map[string]interface{}{
  440 + "companyId": request.CompanyId,
  441 + "orgId": request.OrgId,
  442 + "workshopId": request.WorkshopId,
  443 + "orderBy": "device_name asc"})
  444 + if err != nil {
  445 + return nil, err
  446 + }
  447 +
  448 + type record struct {
  449 + Oee float64 `json:"oee"`
  450 + Pu float64 `json:"pu"`
  451 + Tu float64 `json:"tu"`
  452 + Qu float64 `json:"qu"`
  453 + UpTime int `json:"up_time"`
  454 + T int `json:"t"`
  455 + DeviceId int `json:"device_id"`
  456 + DeviceCode string `json:"device_code"`
  457 + DeviceName string `json:"device_name"`
  458 + // 生产单个产品的时间(单位:秒)
  459 + UnitProductionSecTime float64 `json:"unit_time"`
  460 + // 投入量
  461 + InputWeight float64 `json:"input_weight"`
  462 + // 二级品
  463 + SecondLevelWeight float64 `json:"second_level_weight"`
  464 + }
  465 + var records = make([]*record, 0)
  466 + if err := deviceDailyRunningRecordDao.DeviceProductionEfficiencyStatistics(request.CompanyId,
  467 + request.OrgId,
  468 + request.WorkshopId,
  469 + utils.GetCurrentMonthFirstDay(time.Now()), &records); err != nil {
  470 + log.Logger.Error(err.Error())
  471 + return nil, err
  472 + }
  473 + type production struct {
  474 + WorkStationId string `json:"work_station_id"`
  475 + InputWeight float64 `json:"input_weight"`
  476 + SecondLevelWeight float64 `json:"second_level_weight"`
  477 + }
  478 + var productions = make([]*production, 0)
  479 + workshopProductRecordDao, _ := dao.NewWorkshopProductRecordDao(ptr.transactionContext)
  480 + if err := workshopProductRecordDao.WorkStationProductionStatistics(request.CompanyId,
  481 + request.OrgId,
  482 + request.WorkshopId,
  483 + utils.GetCurrentMonthFirstDay(time.Now()), &productions); err != nil {
  484 + log.Logger.Error(err.Error())
  485 + return nil, err
  486 + }
  487 +
  488 + var response = make([]interface{}, 0)
  489 +
  490 + for i := 0; i < len(devices); i++ {
  491 + d := devices[i]
  492 + if d.Ext == nil || d.Ext.DeviceExt == nil || d.Ext.DeviceExt.IsProductDevice == 0 {
  493 + continue
  494 + }
  495 + var r *record
  496 + for j := 0; j < len(records); j++ {
  497 + if d.DeviceCode == records[j].DeviceCode {
  498 + r = records[j]
  499 + break
  500 + }
  501 + }
  502 + if r != nil {
  503 + r.DeviceName = d.DeviceName
  504 + if d.Ext.DeviceExt != nil {
  505 + r.UnitProductionSecTime = d.Ext.DeviceExt.UnitProductionSecTime
  506 + }
  507 + for k := 0; k < len(productions); k++ {
  508 + if productions[k].WorkStationId == d.WorkStation.WorkStationId {
  509 + r.InputWeight = productions[k].InputWeight
  510 + r.SecondLevelWeight = productions[k].SecondLevelWeight
  511 + break
  512 + }
  513 + }
  514 + response = append(response, r)
  515 + }
  516 + }
  517 + return map[string]interface{}{
  518 + "devices": response,
  519 + }, nil
  520 +}
  521 +
418 func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) { 522 func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) {
419 if transactionContext == nil { 523 if transactionContext == nil {
420 return nil, fmt.Errorf("transactionContext参数不能为nil") 524 return nil, fmt.Errorf("transactionContext参数不能为nil")
@@ -12,6 +12,7 @@ func init() { @@ -12,6 +12,7 @@ func init() {
12 web.Post("/statistics/daily-productive-statistics", c.CommonStatisticsHandler("DailyProductiveStatistics")) 12 web.Post("/statistics/daily-productive-statistics", c.CommonStatisticsHandler("DailyProductiveStatistics"))
13 web.Post("/statistics/proportion-of-second-level-statistics", c.CommonStatisticsHandler("ProportionOfSecondLevelStatistics")) 13 web.Post("/statistics/proportion-of-second-level-statistics", c.CommonStatisticsHandler("ProportionOfSecondLevelStatistics"))
14 web.Post("/statistics/workshop-production-efficiency-statistics", c.CommonStatisticsHandler("WorkshopProductionEfficiencyStatistics")) 14 web.Post("/statistics/workshop-production-efficiency-statistics", c.CommonStatisticsHandler("WorkshopProductionEfficiencyStatistics"))
  15 + web.Post("/statistics/device-production-efficiency-statistics", c.CommonStatisticsHandler("DeviceProductionEfficiencyStatistics"))
15 web.Post("/statistics/device-running-statistics", c.CommonStatisticsHandler("DeviceRunningStatistics")) 16 web.Post("/statistics/device-running-statistics", c.CommonStatisticsHandler("DeviceRunningStatistics"))
16 web.Post("/statistics/device-running-info", c.CommonStatisticsHandler("DeviceRunningInfo")) 17 web.Post("/statistics/device-running-info", c.CommonStatisticsHandler("DeviceRunningInfo"))
17 } 18 }