Files
bj_power/bj_power_mes/internal/logic/product.go
T
SunYF 932700ca65 refactor: 清理MES端本地product_type冗余代码,对齐WMS主数据架构
1.  移除MES端本地product_type实体、schema及相关CRUD代码,改为通过WMS内部API代理获取物料主数据
2.  更新物料管理粒度逻辑,新增"其他"类型(3)支持,同步更新入库校验规则
3.  修复前端物料选择、库存筛选等页面的类型判断逻辑,统一使用manage_mode区分管理类型
4.  清理静态资源文件冗余的样式代码,调整前端页面展示逻辑
5.  更新帮助文档,修正物料类型的说明描述
2026-09-22 07:41:40 +08:00

136 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logic
import (
"context"
"errors"
"fmt"
"strings"
"bj_power_mes/ent/bomitem"
"bj_power_mes/ent/workorder"
"bj_power_mes/internal/wmsclient"
)
// 产品型号(成品档案):编码主数据单一来源 = WMSmaterials item_type=3)。
// MES 本页实时代理 WMS;不再保留本地 product_types 缓存/双写(方案 A:WMS 不可达即报错,
// 不降级读本地缓存,避免给界面喂空/陈旧数据)。
type ProductTypeReq struct {
Id int `json:"id"`
Name string `json:"name"`
Code string `json:"code"`
Spec string `json:"spec"`
Unit string `json:"unit"`
Category string `json:"category"`
IsActive bool `json:"isActive"`
}
func (s *Service) CreateProductType(ctx context.Context, req ProductTypeReq) error {
active := req.IsActive
if !req.IsActive {
active = true
}
if strings.TrimSpace(req.Name) == "" {
return errors.New("名称为必填项")
}
if strings.TrimSpace(req.Spec) == "" {
return errors.New("规格型号为必填项")
}
if strings.TrimSpace(req.Unit) == "" {
return errors.New("单位为必填项")
}
if err := s.ctx.Wms.CreateProductType(ctx, req.Code, req.Name, req.Spec, req.Unit, req.Category, active); err != nil {
return errors.New("WMS 不可达或拒绝写入(编码主数据以 WMS 为单一来源):" + err.Error())
}
return nil
}
func (s *Service) UpdateProductType(ctx context.Context, req ProductTypeReq) error {
if req.Id == 0 {
return errors.New("缺少 id")
}
if strings.TrimSpace(req.Name) == "" {
return errors.New("名称为必填项")
}
if strings.TrimSpace(req.Spec) == "" {
return errors.New("规格型号为必填项")
}
if strings.TrimSpace(req.Unit) == "" {
return errors.New("单位为必填项")
}
if err := s.ctx.Wms.UpdateProductType(ctx, req.Id, req.Name, req.Spec, req.Unit, req.Category, req.IsActive); err != nil {
return errors.New("WMS 不可达或拒绝写入:" + err.Error())
}
return nil
}
// DeleteProductType 删除保护:被工单/BOM 引用过的型号禁删(MES 侧引用校验,
// WMS 侧库存引用由 WMS 内部接口再校验一层)
func (s *Service) DeleteProductType(ctx context.Context, id int) error {
row, err := s.ProductTypeByID(ctx, id)
if err != nil {
return err
}
woCnt, _ := s.ctx.EntClient.WorkOrder.Query().Where(workorder.ProductCode(row.Code)).Count(ctx)
if woCnt > 0 {
return fmt.Errorf("该物料档案已被 %d 张工单引用,不可删除;建议停用(下架)", woCnt)
}
bomCnt, _ := s.ctx.EntClient.BomItem.Query().Where(bomitem.ProductCode(row.Code)).Count(ctx)
if bomCnt > 0 {
return fmt.Errorf("该物料档案在物料清单中有 %d 条配置,不可删除;建议停用(下架)", bomCnt)
}
if err := s.ctx.Wms.DeleteProductType(ctx, id); err != nil {
return errors.New("WMS 不可达或拒绝删除:" + err.Error())
}
return nil
}
// ListProductTypes 全量列表(下拉/兼容形态,id asc 新建在底部)。
// 纯 WMS 代理:WMS 不可达直接报错(不再降级本地缓存)。degraded 恒为 true(仅兼容前端字段)。
func (s *Service) ListProductTypes(ctx context.Context) ([]wmsclient.ProductTypeRow, bool, error) {
list, err := s.ctx.Wms.ProductTypes(ctx, "")
if err != nil {
return nil, false, errors.New("WMS 不可达,无法读取成品档案:" + err.Error())
}
return list, true, nil
}
// ListProductTypesPage 分页+搜索(管理页真分页)。
// 2026-09-08 禁止关键字混搜:编码/名称/类别各自独立模糊。
// 纯 WMS 代理:WMS 不可达直接报错。wmsOnline 恒为 true(仅兼容前端字段)。
func (s *Service) ListProductTypesPage(ctx context.Context, code, name, category, isActive string, page, pageSize int) (int64, []wmsclient.ProductTypeRow, bool, error) {
total, list, err := s.ctx.Wms.ProductTypePage(ctx, code, name, category, isActive, page, pageSize)
if err != nil {
return 0, nil, false, errors.New("WMS 不可达,无法读取成品档案:" + err.Error())
}
return total, list, true, nil
}
// ProductTypeByID 从 WMS 取成品档案(item_type=3)按 idWMS 不可达即报错。
func (s *Service) ProductTypeByID(ctx context.Context, id int) (*wmsclient.ProductTypeRow, error) {
list, err := s.ctx.Wms.ProductTypes(ctx, "")
if err != nil {
return nil, errors.New("WMS 不可达,无法读取成品档案:" + err.Error())
}
for i := range list {
if list[i].ID == id {
return &list[i], nil
}
}
return nil, errors.New("物料档案不存在")
}
// ProductTypeByCode 从 WMS 取成品档案按 code。
func (s *Service) ProductTypeByCode(ctx context.Context, code string) (*wmsclient.ProductTypeRow, error) {
list, err := s.ctx.Wms.ProductTypes(ctx, "")
if err != nil {
return nil, errors.New("WMS 不可达,无法读取成品档案:" + err.Error())
}
for i := range list {
if list[i].Code == code {
return &list[i], nil
}
}
return nil, errors.New("物料档案不存在")
}