refactor: 重构工艺工序相关命名与数据模型

1.  全局替换"工序"为"工艺"统一术语,包括页面文案、枚举、注释
2.  重构工单与工件工艺数据模型:
    - 新增工艺组合表flow_material作为备料/齐套唯一源头
    - 新增工位状态表station_state支持自主停单/恢复接单
    - 移除station_process派工表,改用工单工艺组合作为路线唯一源头
    - 替换processCode为flowId作为工艺关联标识
    - 重构工件当前进度字段为currentStationNo
3.  删除冗余的静态备份资源文件
4.  调整物料选择组件默认启用仅显示激活物料
5.  优化工单创建/编辑逻辑,新增工艺组合校验与保存
This commit is contained in:
SunYF
2026-09-22 11:32:29 +08:00
parent 932700ca65
commit d609ff8a9e
185 changed files with 8623 additions and 4501 deletions
+60 -12
View File
@@ -22,13 +22,13 @@ func parseDate(v string) (time.Time, error) {
}
type DailyPlanReq struct {
Id int `json:"id"`
OrderNo string `json:"orderNo"`
PlanDate string `json:"planDate"`
PlanQty int `json:"planQty"`
CompletedQty int `json:"completedQty"`
Status string `json:"status"`
StationPlanQty map[string]int `json:"stationPlanQty"` // 工位号(字符串键)→计划产量分配;缺省按路线均分
Id int `json:"id"`
OrderNo string `json:"orderNo"`
PlanDate string `json:"planDate"`
PlanQty int `json:"planQty"`
CompletedQty int `json:"completedQty"`
Status string `json:"status"`
StationPlanQty map[string]int `json:"stationPlanQty"` // 工位号(字符串键)→计划产量分配;缺省按路线均分
// 批量排产(新建时与 PlanDate 二选一):日期范围 [start,end] + 分摊模式
PlanRange []string `json:"planRange"` // [start,end] yyyy-MM-dd,批量生成多条日排产
Mode string `json:"mode"` // AVG(平均分摊)/FIXED(固定日产);单条保存时忽略
@@ -51,6 +51,10 @@ func (s *Service) SaveDailyPlan(ctx context.Context, req DailyPlanReq, operator
if wo.Status == "PAUSED" {
return errors.New("该工单已暂停,恢复执行前不能新增排产")
}
// 排产继承工单工艺组合(唯一路线源头):组合未配置或工位改绑工艺后禁止排产
if err := s.ValidateWOCombinationForSchedule(ctx, wo); err != nil {
return err
}
// 批量排产(新建 + 日期范围):一键生成多天日排产,参考工单「自动排产」
if req.Id == 0 && len(req.PlanRange) == 2 && req.PlanRange[0] != "" && req.PlanRange[1] != "" {
return s.saveDailyPlanBatch(ctx, req, operator, wo)
@@ -202,14 +206,18 @@ func (s *Service) saveDailyPlanBatch(ctx context.Context, req DailyPlanReq, oper
return nil
}
// SuggestedDockCodes 查今日工位派工(station_process)路线覆盖的接驳台编码(DOCKxx),供排产/备料默认推荐。
// 路线由工位派工定义,接驳台由各派工工位引用(station.dockCode),因此可直接由路线派生。
// SuggestedDockCodes 查工单工艺组合覆盖工位的接驳台编码(DOCKxx),供排产/备料默认推荐。
// 路线唯一源头 = 工单 flow_combination(按工位号升序),接驳台取 station.dock_code。
func (s *Service) SuggestedDockCodes(ctx context.Context, orderNo string) []string {
route, err := RouteStations(ctx, s.ctx.EntClient, TodayStr(), "")
if err != nil || len(route) == 0 {
wo, err := s.ctx.EntClient.WorkOrder.Query().Where(workorder.WorkOrderNo(orderNo)).First(ctx)
if err != nil {
return nil
}
sts, err := s.ctx.EntClient.Station.Query().Where(station.StationNoIn(route...)).All(ctx)
items, _ := RouteStationsFromWO(ctx, s.ctx.EntClient, wo)
if len(items) == 0 {
return nil
}
sts, err := s.ctx.EntClient.Station.Query().Where(station.StationNoIn(RouteStationsOfWO(items)...)).All(ctx)
if err != nil {
return nil
}
@@ -279,6 +287,42 @@ func (s *Service) ListDailyPlans(ctx context.Context, orderNo, planDate string)
return q.Order(ent.Desc(dailyplan.FieldPlanDate)).All(ctx)
}
// DailyPlanRow 日排产行(附工单工艺组合,供前端派生路线/接驳台展示)
type DailyPlanRow struct {
*ent.DailyPlan
FlowCombination []map[string]int `json:"flowCombination"`
}
// ListDailyPlansWithCombination 日排产列表 + 每行附带所属工单的工艺组合
func (s *Service) ListDailyPlansWithCombination(ctx context.Context, orderNo, planDate string) ([]*DailyPlanRow, error) {
plans, err := s.ListDailyPlans(ctx, orderNo, planDate)
if err != nil {
return nil, err
}
orderNos := make([]string, 0, len(plans))
seen := map[string]bool{}
for _, p := range plans {
if !seen[p.OrderNo] {
seen[p.OrderNo] = true
orderNos = append(orderNos, p.OrderNo)
}
}
combByOrder := map[string][]map[string]int{}
if len(orderNos) > 0 {
wos, err := s.ctx.EntClient.WorkOrder.Query().Where(workorder.WorkOrderNoIn(orderNos...)).All(ctx)
if err == nil {
for _, wo := range wos {
combByOrder[wo.WorkOrderNo] = wo.FlowCombination
}
}
}
rows := make([]*DailyPlanRow, 0, len(plans))
for _, p := range plans {
rows = append(rows, &DailyPlanRow{DailyPlan: p, FlowCombination: combByOrder[p.OrderNo]})
}
return rows, nil
}
// DeleteDailyPlan 删除一条日排产记录
func (s *Service) DeleteDailyPlan(ctx context.Context, id int) error {
return s.ctx.EntClient.DailyPlan.DeleteOneID(id).Exec(ctx)
@@ -396,6 +440,10 @@ func (s *Service) AutoSchedule(ctx context.Context, req AutoScheduleReq, operato
if wo.Status == "PAUSED" {
return errors.New("该工单已暂停,恢复执行前不能排产")
}
// 自动排产继承工单工艺组合(唯一路线源头,不可改):先校验组合与工位绑定一致
if err := s.ValidateWOCombinationForSchedule(ctx, wo); err != nil {
return err
}
remain, err := s.unscheduledQty(ctx, wo)
if err != nil {
return err