作者 yangfu

feat:设备启动状态统计

@@ -45,6 +45,9 @@ func (crontabService *CrontabService) initTask() { @@ -45,6 +45,9 @@ func (crontabService *CrontabService) initTask() {
45 45
46 autoFlushDeviceDailyRunningRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 */1 * * * *", AutoFlushDeviceDailyRunningRecord) 46 autoFlushDeviceDailyRunningRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 */1 * * * *", AutoFlushDeviceDailyRunningRecord)
47 task.AddTask("autoFlushDeviceDailyRunningRecord", autoFlushDeviceDailyRunningRecord) 47 task.AddTask("autoFlushDeviceDailyRunningRecord", autoFlushDeviceDailyRunningRecord)
  48 +
  49 + autoWorkshopPlanCompletionRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 1 1-10/3 * * *", AutoWorkshopPlanCompletionRecord)
  50 + task.AddTask("autoWorkshopPlanCompletionRecord", autoWorkshopPlanCompletionRecord)
48 } 51 }
49 52
50 func (crontabService *CrontabService) StartCrontabTask() { 53 func (crontabService *CrontabService) StartCrontabTask() {
  1 +package crontab
  2 +
  3 +import (
  4 + "context"
  5 + "fmt"
  6 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
  11 + "time"
  12 +)
  13 +
  14 +// 定时刷新车间计划完成纪录
  15 +func AutoWorkshopPlanCompletionRecord(ctx context.Context) error {
  16 + defer func() {
  17 + if r := recover(); r != nil {
  18 + log.Logger.Error(fmt.Sprintf("%v", r))
  19 + }
  20 + }()
  21 + transactionContext, err := factory.CreateTransactionContext(nil)
  22 + if err != nil {
  23 + return err
  24 + }
  25 + if err := transactionContext.StartTransaction(); err != nil {
  26 + return err
  27 + }
  28 + defer func() {
  29 + if err != nil {
  30 + log.Logger.Error("【定时刷新设备每日运行记录】 失败:" + err.Error())
  31 + }
  32 + transactionContext.RollbackTransaction()
  33 + }()
  34 +
  35 + log.Logger.Debug("【定时刷新设备每日运行记录】 启动")
  36 + end := utils.GetZeroTime(time.Now())
  37 + begin := utils.GetZeroTime(end.Add(-time.Second))
  38 + approveAttendanceRecordsService, _ := domainService.NewPGWorkshopPlanCompletionRecordService(transactionContext.(*pgTransaction.TransactionContext))
  39 +
  40 + if err = approveAttendanceRecordsService.WorkshopPlanCompletion(begin, end); err != nil {
  41 + return err
  42 + }
  43 +
  44 + if err = transactionContext.CommitTransaction(); err != nil {
  45 + return err
  46 + }
  47 + return nil
  48 +}
@@ -166,9 +166,78 @@ func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 { @@ -166,9 +166,78 @@ func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 {
166 // 23:00 1 166 // 23:00 1
167 // 23:59 2 167 // 23:59 2
168 // [{"min":1,"time":"00:01","status":1}] 168 // [{"min":1,"time":"00:01","status":1}]
169 -func (d *DeviceRunningRecordInfo) HourDeviceStatusDetail() {  
170 - for i := 0; i < 24; i++ { 169 +func (d *DeviceRunningRecordInfo) HourDeviceStatusDetail(endTime int) map[string]interface{} {
  170 + on := make([][]int, 0)
  171 + off := make([][]int, 0)
  172 + err := make([][]int, 0)
  173 + var begin, end int = 0, 0
  174 + var status = 1 // 1.故障:1 0 \ 0 0 2.正常:1 1 3.停机:0 1
  175 + addToStatus := func(s []int, status int) {
  176 + switch status {
  177 + case 1:
  178 + err = append(err, s)
  179 + break
  180 + case 2:
  181 + on = append(on, s)
  182 + break
  183 + case 3:
  184 + off = append(off, s)
  185 + break
  186 + }
  187 + }
  188 + computeStatus := func(up, com int, index int) int {
  189 + var val = 0
  190 + if up&index > 0 {
  191 + val |= 1
  192 + }
  193 + if com&index > 0 {
  194 + val |= 2
  195 + }
  196 + if val == 1 || val == 0 {
  197 + return 1 //故障
  198 + }
  199 + if val == 3 {
  200 + return 2 //正常
  201 + }
  202 + return 3 // 停机
  203 + }
171 204
  205 + for i := 0; i < 24; i++ {
  206 + var index = 1
  207 + var hds *HourDeviceStatus
  208 + var ok bool
  209 + if hds, ok = d.TimeLineDeviceStatus[fmt.Sprintf("%v", i)]; !ok {
  210 + hds = &HourDeviceStatus{Window: DefaultTimeWindow}
  211 + }
  212 + if i == 0 {
  213 + status = computeStatus(hds.Up, hds.Com, index) // 状态初始化
  214 + }
  215 + if end >= endTime {
  216 + break
  217 + }
  218 + if hds.Up == 0 && hds.Com == 0 {
  219 + end += 60 / hds.Window
  220 + continue
  221 + }
  222 + for j := 1; j < 60; j++ {
  223 + curStatus := computeStatus(hds.Up, hds.Com, index)
  224 + if curStatus == status {
  225 + end += 1
  226 + //continue
  227 + } else {
  228 + addToStatus([]int{begin, end}, status)
  229 + status = curStatus
  230 + begin = end + 1
  231 + end = begin
  232 + }
  233 + index = index << 1
  234 + }
  235 + }
  236 + addToStatus([]int{begin, end}, status)
  237 + return map[string]interface{}{
  238 + "on": on,
  239 + "off": off,
  240 + "err": err,
172 } 241 }
173 } 242 }
174 243
  1 +package dao
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
  8 + "time"
  9 +)
  10 +
  11 +type WorkshopPlanCompletionRecordDao struct {
  12 + transactionContext *pgTransaction.TransactionContext
  13 +}
  14 +
  15 +func (dao *WorkshopPlanCompletionRecordDao) Records(companyId, orgId int, workshopId int, begin, end time.Time, records interface{}) error {
  16 + tx := dao.transactionContext.PgTx
  17 + sql := fmt.Sprintf(`
  18 +with product_record as (
  19 +select
  20 +(case when product_record_type=1 then cast(product_record_info->>'weigh' as DECIMAL)
  21 +ELSE -(cast(product_record_info->>'weigh' as DECIMAL))
  22 +END) as weight,
  23 +cast(product_record_info->>'productPlanId' as INTEGER) plan_id
  24 +--,created_at
  25 +from manufacture.product_records
  26 +where company_id = ?
  27 +and org_id =?
  28 +and work_station->>'workshopId'='?'
  29 +and product_record_type in (1,2)
  30 +and created_at>=?
  31 +and created_at<?
  32 +), product_record_sum as(
  33 + select sum(weight) weight,plan_id from product_record
  34 + GROUP BY plan_id
  35 +)
  36 +select
  37 +plan_devoted->>'weight' plan_weight -- 计划重量
  38 +, coalesce(b.weight,0) real_weight --批次实际产能
  39 +,a.product_plan_id
  40 +from manufacture.product_plan a left join product_record_sum b on a.product_plan_id = b.plan_id
  41 +where company_id = ?
  42 +and org_id =?
  43 +and workshop->>'workshopId'='?'
  44 +and created_at >=?
  45 +and created_at<?
  46 +order by created_at desc`)
  47 + if _, err := tx.Query(records, sql,
  48 + companyId, orgId, workshopId, begin, end,
  49 + companyId, orgId, workshopId, begin, end); err != nil {
  50 + return err
  51 + }
  52 + return nil
  53 +}
  54 +
  55 +func (dao *WorkshopPlanCompletionRecordDao) FindOne(companyId, orgId int, workshopId int, begin time.Time) (*models.WorkshopPlanCompletionRecord, error) {
  56 + tx := dao.transactionContext.PgTx
  57 + var record = new(models.WorkshopPlanCompletionRecord)
  58 + q := tx.Model(record)
  59 + q.Where("company_id=?", companyId)
  60 + q.Where("org_id=?", orgId)
  61 + q.Where("workshop_id=?", workshopId)
  62 + q.Where("created_at=?", begin)
  63 + err := q.First()
  64 + if err != nil {
  65 + if err.Error() == "pg: no rows in result set" {
  66 + return nil, domain.ErrorNotFound
  67 + } else {
  68 + return nil, err
  69 + }
  70 + }
  71 + return record, nil
  72 +}
  73 +
  74 +func (dao *WorkshopPlanCompletionRecordDao) Save(record *models.WorkshopPlanCompletionRecord) error {
  75 + tx := dao.transactionContext.PgTx
  76 + if _, err := tx.Model(record).Insert(); err != nil {
  77 + return err
  78 + }
  79 + return nil
  80 +}
  81 +
  82 +func NewWorkshopPlanCompletionRecordDao(transactionContext *pgTransaction.TransactionContext) (*WorkshopPlanCompletionRecordDao, error) {
  83 + if transactionContext == nil {
  84 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  85 + } else {
  86 + return &WorkshopPlanCompletionRecordDao{
  87 + transactionContext: transactionContext,
  88 + }, nil
  89 + }
  90 +}
@@ -284,6 +284,7 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s @@ -284,6 +284,7 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s
284 } 284 }
285 var r *domain.DeviceDailyRunningRecord 285 var r *domain.DeviceDailyRunningRecord
286 item := make(map[string]interface{}) 286 item := make(map[string]interface{})
  287 + //item["id"] = uuid.New().String()
287 item["orgName"] = d.Ext.OrgName 288 item["orgName"] = d.Ext.OrgName
288 if d.WorkStation != nil { 289 if d.WorkStation != nil {
289 item["workshopName"] = d.WorkStation.WorkshopName 290 item["workshopName"] = d.WorkStation.WorkshopName
@@ -300,7 +301,9 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s @@ -300,7 +301,9 @@ func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[s
300 } 301 }
301 } 302 }
302 if r != nil { 303 if r != nil {
303 - item["status"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus 304 + m := r.UpdatedAt.Hour()*60 + r.UpdatedAt.Minute()
  305 + item["status"] = r.DeviceRunningRecordInfo.HourDeviceStatusDetail(m)
  306 + item["status_info"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus
304 } 307 }
305 response = append(response, item) 308 response = append(response, item)
306 } 309 }
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"
  11 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
  12 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
  13 + "time"
  14 +)
  15 +
  16 +type PGWorkshopPlanCompletionRecordService struct {
  17 + transactionContext *pgTransaction.TransactionContext
  18 +}
  19 +
  20 +func NewPGWorkshopPlanCompletionRecordService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopPlanCompletionRecordService, error) {
  21 + if transactionContext == nil {
  22 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  23 + } else {
  24 + return &PGWorkshopPlanCompletionRecordService{
  25 + transactionContext: transactionContext,
  26 + }, nil
  27 + }
  28 +}
  29 +
  30 +// 车间完成统计
  31 +func (ptr *PGWorkshopPlanCompletionRecordService) WorkshopPlanCompletion(begin time.Time, end time.Time) error {
  32 + type record struct {
  33 + PlanWeight float64 `json:"plan_weight"`
  34 + RealWeight float64 `json:"real_weight"`
  35 + ProductPlanId float64 `json:"product_plan_id"`
  36 + }
  37 + cid := constant.MANUFACTURE_DEFAULT_COMPANYID
  38 + oid := constant.MANUFACTURE_DEFAULT_ORGID
  39 + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext)
  40 + _, workshops, err := workshopRepository.Find(map[string]interface{}{"companyId": cid, "orgId": oid})
  41 + if err != nil {
  42 + return err
  43 + }
  44 + if len(workshops) == 0 {
  45 + return nil
  46 + }
  47 + workshopProductRecordDao, _ := dao.NewWorkshopPlanCompletionRecordDao(ptr.transactionContext)
  48 + for i := range workshops {
  49 + var result = make([]*record, 0)
  50 + if err := workshopProductRecordDao.Records(cid, oid, workshops[i].WorkshopId, begin, end, &result); err != nil {
  51 + log.Logger.Error(err.Error())
  52 + continue
  53 + }
  54 + var totalPlan float64 = 0
  55 + var totalReal float64 = 0
  56 + for _, v := range result {
  57 + totalPlan += v.PlanWeight
  58 + totalReal += v.RealWeight
  59 + }
  60 + var completionRate float64
  61 + if !(totalPlan == 0 || totalReal == 0) {
  62 + completionRate = utils.Round(totalReal*100.0/totalPlan, 0)
  63 + }
  64 +
  65 + var record *models.WorkshopPlanCompletionRecord
  66 + if record, err = workshopProductRecordDao.FindOne(cid, oid, workshops[i].WorkshopId, begin); err == domain.ErrorNotFound && record == nil {
  67 + record = &models.WorkshopPlanCompletionRecord{
  68 + CompanyId: cid,
  69 + OrgId: oid,
  70 + WorkshopId: workshops[i].WorkshopId,
  71 + WorkshopName: workshops[i].WorkshopName,
  72 + CreatedAt: begin,
  73 + Plan: totalPlan,
  74 + Real: totalReal,
  75 + Rate: completionRate,
  76 + }
  77 + if err := workshopProductRecordDao.Save(record); err != nil {
  78 + return err
  79 + }
  80 + }
  81 + }
  82 +
  83 + return nil
  84 +}
@@ -46,6 +46,7 @@ func init() { @@ -46,6 +46,7 @@ func init() {
46 (*models.ProductPlanDispatchRecord)(nil), 46 (*models.ProductPlanDispatchRecord)(nil),
47 (*models.DeviceDailyRunningRecord)(nil), 47 (*models.DeviceDailyRunningRecord)(nil),
48 (*models.DeviceRunningRecord)(nil), 48 (*models.DeviceRunningRecord)(nil),
  49 + (*models.WorkshopPlanCompletionRecord)(nil),
49 } { 50 } {
50 err := DB.Model(model).CreateTable(&orm.CreateTableOptions{ 51 err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
51 Temp: false, 52 Temp: false,
  1 +package models
  2 +
  3 +import (
  4 + "time"
  5 +)
  6 +
  7 +// 车间计划完成记录
  8 +type WorkshopPlanCompletionRecord struct {
  9 + tableName string `comment:"车间" pg:"manufacture.workshop_plan_completion_record"`
  10 + WorkshopPlanCompletionRecordId int `comment:"车间计划完成记录ID" pg:"pk:workshop_plan_completion_record_id"`
  11 + // 企业id
  12 + CompanyId int `comment:"企业id"`
  13 + // 组织ID
  14 + OrgId int `comment:"组织ID"`
  15 + // 生产计划ID
  16 + //ProductPlanId int `comment:"生产计划ID" pg:"pk:product_plan_id"`
  17 + // 工作位置
  18 + //WorkStation *domain.WorkStation `comment:"工作位置"`
  19 + // 车间ID
  20 + WorkshopId int `comment:"车间"`
  21 + // 车间名称
  22 + WorkshopName string `comment:"车间名称"`
  23 + // 创建时间
  24 + CreatedAt time.Time `comment:"创建时间"`
  25 + // 计划生成
  26 + Plan float64 `comment:"计划生成" pg:",use_zero"`
  27 + // 计划生成
  28 + Real float64 `comment:"实际生产" pg:",use_zero"`
  29 + // 完成率
  30 + Rate float64 `comment:"完成率" pg:",use_zero"`
  31 +}