feat(mes): 添加定时同步可生产数量到WMS及BOM项相关标准字段
- 在main.go中添加定时任务每10分钟同步可生产数量到WMS系统 - 为BomItem实体添加relatedStandard字段及相关CRUD方法 - 为InspectionRecord实体添加reportNo、materialCode、materialName等字段 - 更新ent schema确保新字段的验证和默认值设置 - 添加必要的数据库迁移和字段映射逻辑
This commit is contained in:
@@ -165,7 +165,8 @@ func (s *Service) SaveFlow(ctx context.Context, req FlowReq, operator string) er
|
||||
}
|
||||
rec, err := s.ctx.EntClient.ProcessStep.Create().
|
||||
SetFlowId(flowID).SetSeq(st.Seq).SetName(st.Name).
|
||||
SetCollectType(st.CollectType).SetIsTorque(st.IsTorque).SetNeedCheck(st.NeedCheck).SetRemark(st.Remark).Save(ctx)
|
||||
SetCollectType(st.CollectType).SetIsTorque(st.IsTorque).SetNeedCheck(st.NeedCheck).
|
||||
SetRemark(st.Remark).SetAttachment(st.Attachment).Save(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -221,7 +222,7 @@ func (s *Service) flowSteps(ctx context.Context, flowId int) []*ProcessStepTempl
|
||||
t := &ProcessStepTemplate{
|
||||
ID: st.ID, Seq: st.Seq,
|
||||
Name: st.Name, CollectType: st.CollectType, IsTorque: st.IsTorque, NeedCheck: st.NeedCheck,
|
||||
Remark: st.Remark, Criteria: []CriterionVO{},
|
||||
Remark: st.Remark, Attachment: st.Attachment, Criteria: []CriterionVO{},
|
||||
}
|
||||
crits, _ := s.ctx.EntClient.StepCriterion.Query().
|
||||
Where(stepcriterion.StepId(st.ID)).All(ctx)
|
||||
@@ -385,15 +386,30 @@ func (s *Service) StationTask(ctx context.Context, stationNo int) (map[string]an
|
||||
}
|
||||
|
||||
// WorkloadRow 绩效/工作量聚合行(按人/按工位/明细三视图共用)
|
||||
// 前端按 camelCase 读取,必须显式标注 json tag(否则 Go 默认序列化为 PascalCase 导致列空白)
|
||||
type WorkloadRow struct {
|
||||
Operator string
|
||||
StationNo string
|
||||
Date string
|
||||
ProcessCode int
|
||||
ProcessName string
|
||||
DoneCount int
|
||||
OkCount int
|
||||
NgCount int
|
||||
Operator string `json:"operator"`
|
||||
StationNo string `json:"stationNo"`
|
||||
Date string `json:"date"`
|
||||
ProcessCode int `json:"processCode"`
|
||||
ProcessName string `json:"processName"`
|
||||
DoneCount int `json:"doneCount"`
|
||||
OkCount int `json:"okCount"`
|
||||
NgCount int `json:"ngCount"`
|
||||
// Item M 绩效效率:作业时长取自 workpiece_process.duration_sec
|
||||
TotalDurationSec int `json:"totalDurationSec"` // 累计作业时长(秒)
|
||||
AvgDurationSec int `json:"avgDurationSec"` // 平均作业时长(秒)=累计/完成数
|
||||
Efficiency float64 `json:"efficiency"` // 效率(件/小时)=完成数/(累计时长/3600)
|
||||
}
|
||||
|
||||
// finalizeWorkloadRow 由累计作业时长与完成数派生平均作业时长与效率
|
||||
func finalizeWorkloadRow(r *WorkloadRow) {
|
||||
if r.DoneCount > 0 {
|
||||
r.AvgDurationSec = r.TotalDurationSec / r.DoneCount
|
||||
}
|
||||
if r.TotalDurationSec > 0 {
|
||||
r.Efficiency = float64(r.DoneCount) / (float64(r.TotalDurationSec) / 3600.0)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Workload(ctx context.Context, operator, stationNo, from, to string,
|
||||
@@ -432,6 +448,7 @@ func (s *Service) Workload(ctx context.Context, operator, stationNo, from, to st
|
||||
agg[k] = row
|
||||
}
|
||||
row.DoneCount++
|
||||
row.TotalDurationSec += r.DurationSec
|
||||
if r.Result == "OK" {
|
||||
row.OkCount++
|
||||
} else {
|
||||
@@ -464,30 +481,20 @@ func (s *Service) Workload(ctx context.Context, operator, stationNo, from, to st
|
||||
o.DoneCount += v.DoneCount
|
||||
o.OkCount += v.OkCount
|
||||
o.NgCount += v.NgCount
|
||||
o.TotalDurationSec += v.TotalDurationSec
|
||||
} else {
|
||||
byOpAgg[opKey] = &WorkloadRow{Operator: v.Operator, DoneCount: v.DoneCount, OkCount: v.OkCount, NgCount: v.NgCount}
|
||||
byOpAgg[opKey] = &WorkloadRow{Operator: v.Operator, DoneCount: v.DoneCount, OkCount: v.OkCount, NgCount: v.NgCount, TotalDurationSec: v.TotalDurationSec}
|
||||
}
|
||||
stKey := v.StationNo
|
||||
if o, ok := byStAgg[stKey]; ok {
|
||||
o.DoneCount += v.DoneCount
|
||||
o.OkCount += v.OkCount
|
||||
o.NgCount += v.NgCount
|
||||
o.TotalDurationSec += v.TotalDurationSec
|
||||
} else {
|
||||
byStAgg[stKey] = &WorkloadRow{StationNo: v.StationNo, DoneCount: v.DoneCount, OkCount: v.OkCount, NgCount: v.NgCount}
|
||||
byStAgg[stKey] = &WorkloadRow{StationNo: v.StationNo, DoneCount: v.DoneCount, OkCount: v.OkCount, NgCount: v.NgCount, TotalDurationSec: v.TotalDurationSec}
|
||||
}
|
||||
}
|
||||
paginateRows := func(all []*ent.WorkpieceProcess, page, size int) (int, []*ent.WorkpieceProcess) {
|
||||
total := len(all)
|
||||
start := (page - 1) * size
|
||||
if start > total {
|
||||
start = total
|
||||
}
|
||||
end := start + size
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
return total, all[start:end]
|
||||
}
|
||||
paginate := func(all []*WorkloadRow, page, size int) (int, []*WorkloadRow) {
|
||||
total := len(all)
|
||||
start := (page - 1) * size
|
||||
@@ -503,22 +510,28 @@ func (s *Service) Workload(ctx context.Context, operator, stationNo, from, to st
|
||||
|
||||
byOpList := make([]*WorkloadRow, 0, len(byOpAgg))
|
||||
for _, v := range byOpAgg {
|
||||
finalizeWorkloadRow(v)
|
||||
byOpList = append(byOpList, v)
|
||||
}
|
||||
sort.Slice(byOpList, func(i, j int) bool { return byOpList[i].Operator < byOpList[j].Operator })
|
||||
byStList := make([]*WorkloadRow, 0, len(byStAgg))
|
||||
for _, v := range byStAgg {
|
||||
finalizeWorkloadRow(v)
|
||||
byStList = append(byStList, v)
|
||||
}
|
||||
sort.Slice(byStList, func(i, j int) bool { return byStList[i].StationNo < byStList[j].StationNo })
|
||||
|
||||
// 明细视图:按 (操作人,工位,日期,工序) 聚合,与前端明细表列(date/doneCount/okCount/ngCount)对齐
|
||||
for _, v := range list {
|
||||
finalizeWorkloadRow(v)
|
||||
}
|
||||
opTotal, byOpPage := paginate(byOpList, opPage, opSize)
|
||||
stTotal, byStPage := paginate(byStList, stPage, stSize)
|
||||
detTotal, detRowsPage := paginateRows(rows, detPage, detSize)
|
||||
detTotal, detList := paginate(list, detPage, detSize)
|
||||
|
||||
return map[string]any{
|
||||
"byOperator": map[string]any{"total": opTotal, "list": byOpPage},
|
||||
"byStation": map[string]any{"total": stTotal, "list": byStPage},
|
||||
"detail": map[string]any{"total": detTotal, "list": detRowsPage},
|
||||
"detail": map[string]any{"total": detTotal, "list": detList},
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user