正在显示
8 个修改的文件
包含
332 行增加
和
3 行删除
| @@ -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 | +} |
-
请 注册 或 登录 后发表评论