chore: 批量完成项目多模块迭代优化
1. 废弃半成品库存表并统一库存主表 2. 修复列表排序与搜索大小写不敏感问题 3. 新增用户最近登录时间、工单BOM名称字段 4. 完善角色管理、工位选择器功能 5. 增加拧紧数据补录、成品自动回流WMS能力 6. 统一导出时间范围校验规则 7. 丰富物料/备料单筛选条件 8. 调整菜单与权限命名适配产品型号业务
This commit is contained in:
@@ -18,6 +18,7 @@ type WorkOrderReq struct {
|
||||
WorkOrderNo string `json:"workOrderNo"`
|
||||
ProductTypeId int `json:"productTypeId"`
|
||||
ProductCode string `json:"productCode"`
|
||||
BomName string `json:"bomName"` // 建单选定的 BOM 名称(同型号多份并存;空=「默认」)
|
||||
ProductName string `json:"productName"`
|
||||
Quantity int `json:"quantity"`
|
||||
ProcessSeq string `json:"processSeq"`
|
||||
@@ -26,13 +27,34 @@ type WorkOrderReq struct {
|
||||
PlanEnd string `json:"planEnd"`
|
||||
}
|
||||
|
||||
// validateBomName 校验该产品型号下是否存在指定名称的 BOM(型号下无任何 BOM 时放行,允许先建单后补 BOM)
|
||||
func (s *Service) validateBomName(ctx context.Context, productCode, bomName string) error {
|
||||
if productCode == "" {
|
||||
return nil
|
||||
}
|
||||
names, err := s.ListBomNames(ctx, productCode)
|
||||
if err != nil {
|
||||
return nil // 查询异常不阻塞建单(与 WMS 降级策略同思路)
|
||||
}
|
||||
if len(names) == 0 {
|
||||
return nil
|
||||
}
|
||||
target := bomNameOrDefault(bomName)
|
||||
for _, n := range names {
|
||||
if n.BomName == target {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("产品型号 %s 下不存在名为「%s」的BOM,请先在物料清单中创建", productCode, target)
|
||||
}
|
||||
|
||||
// CreateWorkOrder 创建工单(状态恒 CREATED,后续用状态流转按钮推进)
|
||||
func (s *Service) CreateWorkOrder(ctx context.Context, req WorkOrderReq, operator string) error {
|
||||
if req.WorkOrderNo == "" {
|
||||
return errors.New("工单号不能为空")
|
||||
}
|
||||
if req.ProductTypeId == 0 {
|
||||
return errors.New("请选择产品类型")
|
||||
return errors.New("请选择产品型号")
|
||||
}
|
||||
if req.Quantity <= 0 {
|
||||
req.Quantity = 1
|
||||
@@ -50,10 +72,14 @@ func (s *Service) CreateWorkOrder(ctx context.Context, req WorkOrderReq, operato
|
||||
return err
|
||||
}
|
||||
req.ProcessSeq = NormalizeProcessSeq(req.ProcessSeq)
|
||||
if err := s.validateBomName(ctx, req.ProductCode, req.BomName); err != nil {
|
||||
return err
|
||||
}
|
||||
b := s.ctx.EntClient.WorkOrder.Create().
|
||||
SetWorkOrderNo(req.WorkOrderNo).
|
||||
SetProductTypeId(req.ProductTypeId).
|
||||
SetProductCode(req.ProductCode).
|
||||
SetBomName(bomNameOrDefault(req.BomName)).
|
||||
SetProductName(req.ProductName).
|
||||
SetQuantity(req.Quantity).
|
||||
SetProcessSeq(req.ProcessSeq).
|
||||
@@ -101,6 +127,12 @@ func (s *Service) UpdateWorkOrder(ctx context.Context, req WorkOrderReq, operato
|
||||
if req.ProductCode != "" {
|
||||
u.SetProductCode(req.ProductCode)
|
||||
}
|
||||
if req.BomName != "" {
|
||||
if err := s.validateBomName(ctx, req.ProductCode, req.BomName); err != nil {
|
||||
return err
|
||||
}
|
||||
u.SetBomName(bomNameOrDefault(req.BomName))
|
||||
}
|
||||
if req.ProductName != "" {
|
||||
u.SetProductName(req.ProductName)
|
||||
}
|
||||
@@ -140,7 +172,7 @@ func (s *Service) ListWorkOrders(ctx context.Context, orderNo, status, productCo
|
||||
if productName != "" {
|
||||
q = q.Where(workorder.ProductNameContains(productName))
|
||||
}
|
||||
return q.Order(ent.Desc(workorder.FieldID)).All(ctx)
|
||||
return q.Order(ent.Desc(workorder.FieldCreatedAt), ent.Desc(workorder.FieldID)).All(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) GetWorkOrder(ctx context.Context, id int) (*ent.WorkOrder, error) {
|
||||
|
||||
Reference in New Issue
Block a user